使用MSBuild构建并将所有输出复制到公共文件夹的问题

时间:2013-05-15 09:14:51

标签: msbuild msbuild-task msbuild-4.0

我们正在尝试编写一个msbuild脚本,该脚本将构建解决方案并将所有已编译的二进制文件和依赖项复制到特定的输出文件夹。虽然我们构建的脚本确实构建并将二进制文件复制到公共文件夹,但我们没有复制依赖项。 这可能与我们使用msbuild任务构建解决方案的方式有关,我们接受任务的目标输出到项目组并迭代项目组以将所有已编译的dll和exes复制到公共文件夹。但这不包括放入每个项目的单个bin文件夹中的依赖dll。

<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
    <ParentSolutionFile />
</PropertyGroup>
<ItemGroup>
    <Assemblies Include="*.dll, *.exe" />
</ItemGroup>
<Target Name="BuildAll">
    <CombinePath BasePath="$(MSBuildProjectDirectory)" Paths="Source\Solutions\xxx.sln">
        <Output TaskParameter="CombinedPaths" PropertyName="ParentSolutionFile" />
    </CombinePath>
    <Message Text="$(ParentSolutionFile)" />
    <MSBuild Projects="$(ParentSolutionFile)">
        <Output TaskParameter="TargetOutputs" ItemName="Assemblies" />
    </MSBuild>
    <Message Text="%(Assemblies.Identity)" />
    <Copy SourceFiles="%(Assemblies.Identity)" DestinationFolder="$(MSBuildProjectDirectory)\Binary" OverwriteReadOnlyFiles="True" SkipUnchangedFiles="True" />
</Target>

将所有二进制文件以及必要的依赖项复制到公共输出文件夹的首选方法是什么?

2 个答案:

答案 0 :(得分:2)

不会覆盖OutputPath单独执行此操作吗?

<MSBuild Projects="$(ParentSolutionFile)" Properties="OutputPath=$(MSBuildProjectDirectory)\Binary">
  <Output TaskParameter="TargetOutputs" ItemName="Assemblies" />
</MSBuild>

完全忽略了复制任务?

答案 1 :(得分:0)

构建过程将最终结果放在OutputPath表示的目录中 - 至少在构建c#项目时。对于C / C ++,内部结构和变量名称完全不同。

因此,理论上,您可以在构建解决方案的MsBuild任务中传递OutputPath。

<MsBuild Projects="$(ParentSolutionFile)"
    Properties="OutputPath=$(MSBuildProjectDirectory)\Binary"/>

但是,csproj文件将无条件地使用以下代码覆盖该值:

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <OutputPath>bin\Debug\</OutputPath>

我已经通过在每个csproj文件中注入我自己的构建系统来解决这个问题。

<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\..\..\build\buildsystem.targets" />

路径相对于csproj文件。绝对路径也可以,或变量。诀窍是让它适用于所有开发机器以及构建代理。

现在,在buildsystem.targets中,只需根据需要重新定义OutputPath即可。同样,诀窍是确保您获得相同的 - 或者至少是一个定义良好的 - 位置,无论是谁构建它(开发,构建代理),也不管构建是如何启动的(VS,命令行)。

处理差异的一种简单方法是有条件地导入。

<Import Project="..\..\..\build\buildsystem.targets"
    Condition="'$(BuildingInsideVisualStudio)'!='true'"/>

如果从命令行构建,如果从VS启动构建以及您编写的任何更改,那将不会给您带来任何更改。

- 的Jesper