我看到了ItemGroup
标记的一些奇怪行为。
我的应用程序依赖于几个DLL,我将这些DLL以及可执行文件复制到部署目录,NSIS使用该目录从新构建创建安装包。但是,我遇到了一个奇怪的问题。
我定义我的ItemGroup
如下(在我定义构建目标之前在文件的顶部:
<MyAppFiles Include="$(ProjectRoot)\$(OutputPath)\*.dll;$(ProjectRoot)\$(OutputPath)\MyApp.exe" />
因此,这会抓取目录中的所有DLL以及二进制MyApp.exe
。但是,如果项目已被清理(即$(OutputPath)
中没有文件)。 DLL不包含在ItemGroup
文件列表中。现在,如果我使用其他版本进行此操作(即$(OutputPath)
中有来自上一版本的文件),ItemGroup
包含我想要的所有文件。
另外,我已经检查了构建脚本的输出,并且DLL被复制到$(OutputPath)
是否发生了干净。
所以,我的问题是,我如何更正我的构建脚本,使ItemGroup
始终包含DLL?在构建发生之前,似乎ItemGroup
填充了文件,因此如果构建之前文件不存在,它们不会包含在列表中,但如果它们在构建之前存在,那么它们就是。< / p>
作为参考,这是我正在使用的构建目标:
<PropertyGroup>
<MyAppRoot>..\MyApp</MyAppRoot>
<MyAppProject>$(MyAppRoot)\MyApp.csproj</MyAppProject>
<PropertyGroup>
<Target Name="BuildProject">
<Message Text="BEFORE: @(ProjectFiles)" />
<MSBuild Projects="$(MyAppProject)" Targets="Build" Properties="Configuration=$(Configuration)">
<Output TaskParameter="TargetOutputs" ItemName="MyAppAssembly"/>
</MSBuild>
<Message Text="AFTER: @(ProjectFiles)" />
</Target>
答案 0 :(得分:9)
据推测,您的项目数组是在项目的根级别声明的,在XML中是&lt; Project&gt;的子级。元件。这意味着MSBuild将在首次加载项目文件时评估项目数组中的成员资格。在执行期间这些文件的存在是否发生变化是无关紧要的。如果要在构建中的特定点填充项目数组,则需要将声明从静态项目数组更改为动态项目,这意味着将其在目标中移动到您要收集的确切位置文件,如:
<Target Name="BuildProject">
...before message
...msbuild task
<ItemGroup>
<ProjectFiles Include="$(ProjectRoot)\$(OutputPath)\*.dll" />
<ProjectFiles Include="$(ProjectRoot)\$(OutputPath)\MyApp.exe" />
</ItemGroup>
...after message
</Target>
(摘自“MSBuild Trickery”一书中的第62号技巧)