我有一个MSBuild文件,我正在构建这样的C#项目:
<ItemGroup>
<ProjectsToBuild Include="./source/ProjectA/ProjectA.csproj"/>
<ProjectsToBuild Include="./source/ProjectB/ProjectB.csproj"/>
</ItemGroup>
<Target Name="Build">
<MSBuild Projects="@(ProjectsToBuild)" Targets="Build">
<Output ItemName="ProjectOutputs" TaskParameter="TargetOutputs"/>
</MSBuild>
<Message Text="@ProjectOutputs"/>
</Target>
Run Code Online (Sandbox Code Playgroud)
我成功获取了一个包含所有构建的.dll文件的Item:
Build:
c:\code\bin\ProjectA.dll;c:\code\bin\ProjectB.dll
Run Code Online (Sandbox Code Playgroud)
我还想从每个项目中获取Content项而不修改.csproj文件.在微软.targets文件中挖掘之后,我几乎能够使用它:
<MSBuild Projects="@(ProjectsToBuild)" Targets="ContentFilesProjectOutputGroup">
<Output ItemName="ContentFiles" TaskParameter="TargetOutputs"/>
</MSBuild>
<Message Text="@(ContentFiles->'%(RelativeDir)')"/>
Run Code Online (Sandbox Code Playgroud)
这种方法的问题是没有正确设置RelativeDir.我正在获得完整的路径而不是相对的:
Build:
c:\ProjectA\MyFolder\MyControl.ascx;c:\ProjectB\MyOtherFolder\MyCSS.css;
Run Code Online (Sandbox Code Playgroud)
代替:
Build:
MyFolder\MyControl.ascx;MyOtherFolder\MyCSS.css;
Run Code Online (Sandbox Code Playgroud)
是否有可以传递给MSBuild任务的属性,这将使RelativeDir行为正常?
或者,更好的是,是否有更简单的方法来获取内容项?
你可以做到这一点,但它不是很直观.我已经在我的博客上讨论了这种类型的技术(目前已经下来了:().
所以创建一个新文件,我把它命名为GetContentFiles.proj,如下所示.
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="3.5" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Projects Include="WindowsFormsApplication1\WindowsFormsApplication1.csproj"/>
</ItemGroup>
<!-- This target will be executed once for each file declared in the Project target -->
<Target Name="PrintFiles" Outputs="%(Projects.Identity)">
<Message Text="PrintFiles" Importance="high"/>
<MSBuild Projects="$(MSBuildProjectFile)"
Targets="GetContentFiles"
Properties="ProjectToGetFiles=%(Projects.Identity)">
<Output ItemName="projContent" TaskParameter="TargetOutputs"/>
</MSBuild>
<Message Text="ProjContent: @(projContent)" Importance="high"/>
<!-- Transform the projContent to have correct path -->
<!--
Get the relative path to the project itself, this serves as the base for
the Content files path
-->
<PropertyGroup>
<_ProjRelativeDir>%(Projects.RelativeDir)</_ProjRelativeDir>
</PropertyGroup>
<!-- This item will contain the item with the corrected path values -->
<ItemGroup>
<ProjContentFixed Include="@(projContent->'$(_ProjRelativeDir)%(RelativeDir)%(Filename)%(Extension)')"/>
</ItemGroup>
<!-- Create a new item with the correct relative dirs-->
<Error Condition="!Exists('%(ProjContentFixed.FullPath)')"
Text="File not found at [%(ProjContentFixed.FullPath)]"/>
</Target>
<Import Project="$(ProjectToGetFiles)" Condition="'$(ProjectToGetFiles)'!=''"/>
<Target Name="GetContentFiles" Condition="'$(ProjectToGetFiles)'!=''" Outputs="@(Content)">
<Message Text="Content : @(Content)" Importance="high"/>
<Message Text="Inside GetContentFiles" Importance="high"/>
</Target>
</Project>
Run Code Online (Sandbox Code Playgroud)
我将尝试解释这一点,但可能很难遵循.如果您需要我扩展它,请告诉我.该文件有两个目标PrintFiles和GetContentFiles.此文件的入口点是PrintFiles目标,因为这是您要调用的目标.因此,您调用PrintFiles目标,然后使用MSBuild任务调用GetContentFiles目标,同时它还传递ProjectToGetFiles属性的值.因此,Import elemnent将被执行.所以你真正做的是获取ProjectToGetFiles属性中定义的项目并将其扩展为包含目标GetContentFiles(以及GetContentFiles.proj文件中的任何其他内容).所以我们正在有效地扩展该文件.我称这种技术为"MSBuild继承",因为.因此,在GetContentFiles目标中,我们可以访问在ProjectToGetFiles属性中声明的所有属性和项.所以我通过简单地将Content项的内容放入目标的输出中来利用它,原始文件可以使用MSBuild任务中的TargetOutputs访问它.
您在帖子中提到您想要将路径值更正为正确的值.这里的问题是在.csproj文件中所有项都是相对于原始项目文件声明的.因此,如果以这种方式从不同目录中的文件"扩展"项目文件,则必须手动更正文件路径值.我在PrintFiles目标中完成了这个,检查出来.
如果执行命令msbuild GetContentFile.proj/fl/t:PrintFiles,结果将是:
Build started 7/3/2009 12:56:35 AM.
Project "C:\Data\Development\My Code\Community\MSBuild\FileWrites\GetContentFile.proj" on node 0 (PrintFiles target(s)).
PrintFiles
Project "C:\Data\Development\My Code\Community\MSBuild\FileWrites\GetContentFile.proj" (1) is building "C:\Data\Development\My Co
de\Community\MSBuild\FileWrites\GetContentFile.proj" (1:2) on node 0 (GetContentFiles target(s)).
Content : Configs\Config1.xml;Configs\Config2.xml
Inside GetContentFiles
Done Building Project "C:\Data\Development\My Code\Community\MSBuild\FileWrites\GetContentFile.proj" (GetContentFiles target(s)).
PrintFiles:
ProjContent: Configs\Config1.xml;Configs\Config2.xml
Done Building Project "C:\Data\Development\My Code\Community\MSBuild\FileWrites\GetContentFile.proj" (PrintFiles target(s)).
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:00:00.03
Run Code Online (Sandbox Code Playgroud)
Sayed Ibrahim Hashimi
我的书:Microsoft Build Engine内部:使用MSBuild和Team Foundation Build
| 归档时间: |
|
| 查看次数: |
6062 次 |
| 最近记录: |