如何获取 Visual Studio 构建过程以创建可分发目录?
How to get Visual Studio build process to create a distributable directory?
我想自定义我的 Visual Studio 解决方案构建以自动创建一个包含 dist -> bin 目录的目录树。 bin 目录应将所有二进制文件自动复制到其中。
注意:解决方案有很多项目,所以我不想自定义项目构建,这应该在解决方案级别。
我已经尝试过两种解决方案:
1) 修改每个项目文件以创建此 dist 目录树(如果它尚不存在)。对于添加到解决方案的每个新项目,我都需要修改项目文件,这对我来说似乎是多余的。
2) 创建解决方案 .targets 文件以通过命令行与 msbuild.exe 一起使用。这完全符合我的要求,但我更喜欢在 visual studio.
内工作的解决方案
如果有人关心,动机是有一种简单的方法来分发新版本,而不必每次都从中提取源代码。
更新:2015 年 5 月 26 日
我想 post 在这里提出我的解决方案,这样遇到同样问题的人就会有解决方案。我最终在与我的解决方案文件相同的目录中创建了一个 ImportBefore 目录。在与解决方案相同的目录中,解决方案中包含的每个项目都有一个目录。这是 visual studio 解决方案的标准结构,该结构很重要,因为 msbuild 每个项目只有一个参考变量。
将包含以下内容的文件放入 $(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\$(MSBuildThisFile)\ImportBefore\
在我的机器上它位于 C:\Program Files (x86)\MSBuild.0\Microsoft.Common.Targets\ImportBefore
我的文件 "importbefore.targets" 如下所示:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ImportPath Condition="'$(ImportPath)'==''">$(MSBuildProjectDirectory)\..\ImportBefore</ImportPath>
</PropertyGroup>
<Import Project="$(ImportPath)\*" Condition="'$(ImportByWildcardBeforeMicrosoftCSharpTargets)' == 'true' and exists('$(ImportPath)')"/>
</Project>
为了测试这是否有效,我将以下目标文件添加到 \ImportBefore 或我的计算机 C:\Users\admin\Dropbox\Projects\BuildTestProject\ImportBefore
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="OnlyIfExists" BeforeTargets="Build" Condition="Exists('$(ImportPath)')">
<Message Text="Found import directory '$(ImportPath)'" Importance="high" />
</Target>
</Project>
最后,我将更新解决方案本地的项目文件以仅在未创建分发目录时创建分发目录,然后将正在构建的当前项目的二进制文件复制到该分发目录。
需要进行一些额外的设置,但是一旦设置完成,它就适用于所有 solutions\projects。
如果您查看 Microsoft.Common.Targets(在 C:\Windows\Microsoft.Net\Framework(MSBuildVersion) 中找到),您会看到它尝试导入许多自定义目标文件.您可以将自己的目标文件放在 $(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\$(MSBuildThisFile)\ImportBefore\ 文件夹中,或者您可以在 $(MSBuildExtensionsPath)\v$(MSBuildToolsVersion) 中创建一个 Custom.Before.Microsoft.Common.targets 文件文件夹。在您的自定义扩展中,您可以添加具有自定义复制命令的 $(SolutionDir)Solution.targets 的导入。由于 Microsoft.Common.Targets 文件用于 C# 和 C++ 编译,因此您的自定义目标将由所有项目类型加载。只要您在您使用的所有 PC 上设置这些文件,就应该没问题。
另一种选择是使用您的自定义命令创建一个 {您的项目名称和扩展名}.user 文件。此解决方案不需要修改 MSBuild 文件夹,但确实需要每个项目都有自己的文件。也就是说,每个 .user 文件都可以加载一个包含复制命令的 $(SolutionDir)\Common.Targets 文件。
无论如何,我只会查看 Microsoft.Common.Targets 文件,看看它在做什么。如果您在文本编辑器中查看 csproj 文件本身,您可以看到它导入的位置 Microsoft.Common.Targets。这将帮助您更好地了解 MSBuild 过程。
我想自定义我的 Visual Studio 解决方案构建以自动创建一个包含 dist -> bin 目录的目录树。 bin 目录应将所有二进制文件自动复制到其中。
注意:解决方案有很多项目,所以我不想自定义项目构建,这应该在解决方案级别。
我已经尝试过两种解决方案:
1) 修改每个项目文件以创建此 dist 目录树(如果它尚不存在)。对于添加到解决方案的每个新项目,我都需要修改项目文件,这对我来说似乎是多余的。
2) 创建解决方案 .targets 文件以通过命令行与 msbuild.exe 一起使用。这完全符合我的要求,但我更喜欢在 visual studio.
内工作的解决方案如果有人关心,动机是有一种简单的方法来分发新版本,而不必每次都从中提取源代码。
更新:2015 年 5 月 26 日
我想 post 在这里提出我的解决方案,这样遇到同样问题的人就会有解决方案。我最终在与我的解决方案文件相同的目录中创建了一个 ImportBefore 目录。在与解决方案相同的目录中,解决方案中包含的每个项目都有一个目录。这是 visual studio 解决方案的标准结构,该结构很重要,因为 msbuild 每个项目只有一个参考变量。
将包含以下内容的文件放入 $(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\$(MSBuildThisFile)\ImportBefore\
在我的机器上它位于 C:\Program Files (x86)\MSBuild.0\Microsoft.Common.Targets\ImportBefore
我的文件 "importbefore.targets" 如下所示:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ImportPath Condition="'$(ImportPath)'==''">$(MSBuildProjectDirectory)\..\ImportBefore</ImportPath>
</PropertyGroup>
<Import Project="$(ImportPath)\*" Condition="'$(ImportByWildcardBeforeMicrosoftCSharpTargets)' == 'true' and exists('$(ImportPath)')"/>
</Project>
为了测试这是否有效,我将以下目标文件添加到 \ImportBefore 或我的计算机 C:\Users\admin\Dropbox\Projects\BuildTestProject\ImportBefore
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="OnlyIfExists" BeforeTargets="Build" Condition="Exists('$(ImportPath)')">
<Message Text="Found import directory '$(ImportPath)'" Importance="high" />
</Target>
</Project>
最后,我将更新解决方案本地的项目文件以仅在未创建分发目录时创建分发目录,然后将正在构建的当前项目的二进制文件复制到该分发目录。
需要进行一些额外的设置,但是一旦设置完成,它就适用于所有 solutions\projects。
如果您查看 Microsoft.Common.Targets(在 C:\Windows\Microsoft.Net\Framework(MSBuildVersion) 中找到),您会看到它尝试导入许多自定义目标文件.您可以将自己的目标文件放在 $(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\$(MSBuildThisFile)\ImportBefore\ 文件夹中,或者您可以在 $(MSBuildExtensionsPath)\v$(MSBuildToolsVersion) 中创建一个 Custom.Before.Microsoft.Common.targets 文件文件夹。在您的自定义扩展中,您可以添加具有自定义复制命令的 $(SolutionDir)Solution.targets 的导入。由于 Microsoft.Common.Targets 文件用于 C# 和 C++ 编译,因此您的自定义目标将由所有项目类型加载。只要您在您使用的所有 PC 上设置这些文件,就应该没问题。
另一种选择是使用您的自定义命令创建一个 {您的项目名称和扩展名}.user 文件。此解决方案不需要修改 MSBuild 文件夹,但确实需要每个项目都有自己的文件。也就是说,每个 .user 文件都可以加载一个包含复制命令的 $(SolutionDir)\Common.Targets 文件。
无论如何,我只会查看 Microsoft.Common.Targets 文件,看看它在做什么。如果您在文本编辑器中查看 csproj 文件本身,您可以看到它导入的位置 Microsoft.Common.Targets。这将帮助您更好地了解 MSBuild 过程。