我正试图将一些简单的MSBuild任务添加到Visual Studio项目(VS 2012学习版)中,特别是创建一个子目录,然后将一些文件复制到输出目录的一个子目录中,以便打包。
我看到VS支持自定义构建步骤,这些步骤是命令行调用。但是,由于VS是基于MSBuild的,因此应该可以将它们直接添加为MSBuild任务,如AfterBuild预定义目标中的Copy Task。
我找不到在Visual Studio框架内实际添加此类任务的任何方法。文档只是从MSBuild的角度讨论它,而不是它如何在VisualStudio的UI中工作。它似乎也没有讨论引用构建输出等的属性;大概它们只是msbuild自己使用的那些。
Visual Studio的UI中是否支持MSBuild任务管理,而它刚刚从我的速成版中被禁用?还是我必须破解项目文件XML才能添加MSBuild任务?这得到了支持吗?应该以什么方式进行?
我习惯于使用Eclipse和Ant或Maven,在IDE中支持所有这些,当然你可以直接破解XML。在Visual Studio中找不到任何用于MSBuild任务管理的UI,这相当令人困惑。我是错过了显而易见的东西,还是因为使用免费版而残废了?
对于C++项目,可以使用属性
<CppCleanDependsOn>DeleteOutputs;$(CppCleanDependsOn)</CppCleanDependsOn>
而不是像您那样定义BeforeClean目标。
从我读到的内容来看,CallTarget是应该避免的。在您的示例中,您应该使用DependsOnTargets来执行此操作,正如您在MS提供的文件中的许多伪目标中看到的那样。一个函数的类似机制(其中一个目标只是"调用"其他目标)是用DependsOnTargets完成的。流程实际上与过程编程不同。
Intellisense:我从来没有用过它。这只适用于props文件中的条件AdditionalIncludeDirectories吗?如果您在IDE中只选择了一个配置来编辑属性,请继续编辑proj文件中IDE放置它的条目。
(经过一系列的阅读,我发现了这是如何工作的):
Visual Studio似乎没有公开高级MSBuild项目编辑,尽管现代vcxproj
文件只是MSBuild工程文件,其中包含一堆额外标记的属性和Visual Studio IDE细节的其他条目。所以你必须破解项目XML。
为了使其更简洁,只需在实际的vcxproj
文件中添加一行即可,这是包含其余构建自定义的.targets
文件的一部分。例如,就在项目文件结束前,插入:
<Import Project="pg_sysdatetime.targets" />
</Build>
现在,使用与任何其他MSBuild项目相同的结构创建.targets
文件。这是我一直在做的项目:
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- MSBuild extension targets for Visual Studio build -->
<PropertyGroup>
<DistDir>pg_sysdatetime_pg$(PGMAJORVERSION)-$(Configuration)-$(Platform)</DistDir>
</PropertyGroup>
<ItemGroup>
<DocFiles Include="README.md;LICENSE"/>
<ExtensionSourceFiles Include="pg_sysdatetime--1.0.sql;pg_sysdatetime.control"/>
<ExtensionDll Include="$(TargetDir)pg_sysdatetime.dll"/>
</ItemGroup>
<Target Name="CopyOutputs">
<Message Text="Copying build product to $(DistDir)" Importance="high" />
<Copy
SourceFiles="@(DocFiles)"
DestinationFolder="$(DistDir)"
/>
<Copy
SourceFiles="@(ExtensionDll)"
DestinationFolder="$(DistDir)lib"
/>
<Copy
SourceFiles="@(ExtensionSourceFiles)"
DestinationFolder="$(DistDir)shareextension"
/>
</Target>
<Target Name="DeleteOutputs">
<Message Text="Deleting $(DistDir)" Importance="normal" />
<Delete Files="$(DistDir)"/>
</Target>
<!-- Attach to Visual Studio build hooks -->
<Target Name="BeforeClean">
<CallTarget Targets="DeleteOutputs"/>
</Target>
<Target Name="AfterBuild">
<CallTarget Targets="CopyOutputs"/>
</Target>
</Project>
它可以包含所需的MSBuild任务,并分组为目标。它还可以具有属性组、项组以及MSBuild支持的任何其他内容。
若要集成到Visual Studio中,需要添加专门命名的目标,以调用所需内容。在这里,您可以看到我已经定义了BeforeClean
和AfterBuild
目标。您可以从VS集成文档中获取支持的目标。
现在,当我构建或重建时,会自动创建一个包含产品DLL和一堆静态文件的新目录,准备进行压缩。如果我愿意的话,我可以为MSBuild社区扩展添加Nuget包,并在最后使用Zip任务将整个东西捆绑到一个Zip文件中。
顺便说一句,虽然您可以在.targets
文件中定义属性,但最好在属性表中定义它们。这样就可以在UI中看到它们。
我使用的是VS2010Pro,它没有公开AfterBuild目标,至少在我正在做的C++项目中是这样。正如您所看到的,它确实有"事件",根据我所读到的内容,它是为了与VSBuild中转换的项目向后兼容。我同意,应该使用MSBuild任务而不是命令脚本。
忘记UI。它是为了支持XML文件的免费编辑,并继续使用UI,因为它尊重您的内容,并为自己的内容使用标签,这样它就可以找到它来更新它
但为了保持整洁,您可以使用属性页;一个名为*.props的独立XML文件,并在其中放入您想要的内容。然后使用UI将该props文件添加到项目中。您不会手动编辑UI正在维护的项目文件,除非您浏览属性管理器视图并明确打开它,否则它也不会触及道具文件。
哦,我还记得看到过其他的标准目标,比如打包和发布。也许这些没有在你的项目类型中使用,但你无论如何都可以使用这些入口点。