从MSBuild项目获取输出文件

17

如何在MSBuild项目中获取所有输出文件的列表?

对于简单的项目,我可以执行以下操作:

<CreateItem Include="$(OutputDir)**\*">
      <Output ItemName="AllOutputs" TaskParameter="Include"/>
</CreateItem>

但我的项目是大型构建的一部分,所有输出都会进入一个共同的位置,我希望能够排除不属于该位置的dll和内容。

有什么想法吗?

3个回答

24

我再次查看了您的评论后,意识到我误解了您真正需要的东西。您手头有一个有趣的问题。

如果您不介意编辑项目文件本身,您可能会接近您想要的目标。有一个名为FileWrites的项目,跟踪了构建过程中写入的所有文件。要开始尝试,请编辑项目文件以具有此AfterBuild目标。

<Target Name="AfterBuild">
  <Message Text="FileWrites: @(FileWrites)" Importance="high"/>
</Target>

但是,这种方法也存在一些问题:

  • 你必须编辑项目文件本身。
  • 这将包含写入到中间输出目录(即obj)和输出目录(即bin)的文件。
  • 如果有构建自定义,则不需要写入此项。

你可能认为可以通过使用MSBuild:查找多个项目引用 技术并在构建后输出 FileWrites 项来解决第一个问题。但是,如果包装项目文件与原始项目本身不在同一文件夹中,则这将无效,因为 .csproj 文件内的所有项均使用相对路径声明。所以这个方法在很大程度上行不通。

你可以通过使用 FindUnderPath 任务来解决第二个限制,只获取放置在OutputPath文件夹中的文件。

你可以尝试做的另一件事情,但也不是特别可靠的方法,就是在构建开始时检查 OutputPath,然后再在构建结束时检查一次,并查看添加了什么。假设你将原始文件放入名为 StartFiles 的项中,并在构建结束时将所有文件放入名为 EndFiles 的项中,那么你可以执行以下操作:

<Target Name="SomeTargetHere">

<ItemGroup>
    <FilesWritten Include="@(EndFiles)" />
    <FilesWritten Remove="@(StartFiles)"/>
</ItemGroup>

<!-- Now FilesWritten contains the difference between EndFiles & StartFiles -->

</Target>

简而言之,我不确定是否有一种好的解决方案,既不涉及自定义任务也不涉及自定义记录器 :(。

Sayed Ibrahim Hashimi

我的书:《深入了解Microsoft Build引擎:使用MSBuild和Team Foundation Build》


12

如果你正在使用MSBuild任务,那么你可以通过使用TargetOutputs输出获取已构建的文件。以下是一个示例:

<MSBuild Projects="YourProject.csproj">
      <Output ItemName="YourProjectOutputs" TaskParameter="TargetOutputs"/>
</MSBuild>

因此,在这种情况下,当YourProject.csproj被构建时,创建的文件将被放置在YourProjectOutputs项目中。

我之前写了一篇博客详细介绍了这个问题,MSBuild: 如何获取所有生成的输出

Sayed Ibrahim Hashimi

我的书:《Inside the Microsoft Build Engine : Using MSBuild and Team Foundation Build》


1
谢谢您的建议,问题在于TargetOutputs仅包括输出程序集,而GetOutputs任务包括输出目录中的所有内容,即使msbuild项目没有创建/复制它。 - Scott Weinstein

3
请看我的上一篇博客文章MSBuild: 查找多个项目引用。在那篇文章中,我描述了如何创建一个MSBuild文件,可以提取Reference ItemGroup的值。针对你的情况,只需使用一个从OutputPath中找到的所有文件填充项的目标替换我创建的目标即可。如果需要进一步解释,请告诉我。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接