MSBuild 项可以使用目标设置的 属性 吗?
Can an MSBuild Item use a Property set by a Target?
我正在尝试使用 MSBuild 实现以下目标:我的主项目 (MyProject.csproj
) 应该包括几个 Reference
项,但是其中一个 Reference
的路径是 SomeProperty
属性 的值,由 Target 设置。具体来说,SomeProperty
的值是使用 ReadLinesFromFileTask
从文件中解析出来的。
这里是MyProject.csproj
的高层结构:
<Project>
<Target Name="CreateSomeProperty">
<!-- Tasks that ultimately set $(SomeProperty) by parsing a value with ReadLinesFromFileTask -->
</Target>
<ItemGroup>
<Reference Include="$(SomeProperty)" />
<!-- Other Reference items -->
</ItemGroup>
</Project>
很遗憾,此设置无效。我在 VS 解决方案资源管理器中的 MyProject
的 Dependencies
节点下看到了那些黄色小三角形,因为该项目正在寻找缺少字符的路径中的 DLL。同样,当我构建项目时,我得到了一堆 The type or namespace name could not be found
错误,即使我仍然在我的目标中看到 Message
任务的输出。据推测,CreatePathProperty
目标在执行阶段是 运行,在 Reference
项在评估阶段加载失败后。
有没有办法让这样的设置工作?我已经尝试在 Target
元素中设置 BeforeTargets="Build"
,并在 Project
元素中设置 InitialTargets="CreateSomeProperty"
,但似乎没有任何效果。任何帮助将不胜感激!
Can an MSBuild Item use a Property set by a Target?
是的,如果你在 .net framework project with old csproj format
并且你想要的是 VS2017 中支持的场景(仅在 VS2017 中进行了测试),我相信这是可能的。
提示:
通常 msbuild
在执行您的自定义目标之前读取 Properties
和 Items
。所以我们应该使用 BeforeTargets="BeforeResolveReferences"
之类的东西来确保在这种情况下正确的顺序是 custom target runs=>create the property=>msbuild reads the info about references and the property
.
否则顺序(BeforeTargets="Build"
或什么时候顺序错误)应该是:Msbuild reads the info about references(now the property is not defined yet)=>the target runs and creates the property
.
解法:
将此脚本添加到 xx.csproj.
的底部
<!-- Make sure it executes before msbuild reads the ItemGroup above and loads the references -->
<Target Name="MyTest" BeforeTargets="BeforeResolveReferences">
<ItemGroup>
<!-- Define a TestFile to represent the file I read -->
<TestFile Include="D:\test.txt" />
</ItemGroup>
<!-- Pass the file to read to the ReadLinesFromFile task -->
<ReadLinesFromFile File="@(TestFile)">
<!--Create the Property that represents the normal hintpath(SomePath\DLLName.dll)-->
<Output TaskParameter="Lines" PropertyName="HintPathFromFile" />
</ReadLinesFromFile>
<!-- Output the HintPath in output log to check if the path is right -->
<Message Text="$(HintPathFromFile)" Importance="high" />
<ItemGroup>
<Reference Include="TestReference">
<!--It actually equals:<HintPath>D:\AssemblyFolder\TestReference.dll</HintPath>-->
<HintPath>$(HintPathFromFile)</HintPath>
</Reference>
</ItemGroup>
</Target>
另外:
我用 test.txt
文件做了测试,其内容是:
我不确定你的文件的实际内容(和格式),但如果你的文件中只有像 D:\AssemblyFolder\
这样的路径,你应该将 D:\AssemblyFolder\+YourAssemblyName.dll
传递给 <HintPath>
元数据。导致带有 hintpath
的 default reference
格式如下所示:
<Reference Include="ClassLibrary1">
<HintPath>path\ClassLibrary1.dll</HintPath>
</Reference>
注意路径格式!希望我的回答对您有所帮助:)
在 msbuild 中,static 项目无法根据设计依赖于 dynamic 属性。
接受的答案提供了一个解决方法:使用动态项目,这自然可以依赖于动态属性。但是动态项不会显示在 IDE.
中
处理文件时,更 IDE 友好的方法是静态创建项目并在目标运行时更新它:
<!-- Static item definition -->
<ItemGroup>
<SomeItem Include="item_file" />
</ItemGroup>
<Target Name="...">
<!-- When the target runs, find the static item using Condition and change its properties -->
<ItemGroup>
<SomeItem Condition="'%(SomeItem.Identity)' == 'item_file'">
<SomeProperty>New Value</SomeProperty>
</SomeItem>
</ItemGroup>
</Target>
还有一个未解决的 msbuild 问题 (#889) 以支持为此改进的语法:
<Target Name="...">
<ItemGroup>
<!-- Update has the same syntax as Include -->
<SomeItem Update="item_file">
<SomeProperty>New Value</SomeProperty>
</SomeItem>
</ItemGroup>
</Target>
我正在尝试使用 MSBuild 实现以下目标:我的主项目 (MyProject.csproj
) 应该包括几个 Reference
项,但是其中一个 Reference
的路径是 SomeProperty
属性 的值,由 Target 设置。具体来说,SomeProperty
的值是使用 ReadLinesFromFileTask
从文件中解析出来的。
这里是MyProject.csproj
的高层结构:
<Project>
<Target Name="CreateSomeProperty">
<!-- Tasks that ultimately set $(SomeProperty) by parsing a value with ReadLinesFromFileTask -->
</Target>
<ItemGroup>
<Reference Include="$(SomeProperty)" />
<!-- Other Reference items -->
</ItemGroup>
</Project>
很遗憾,此设置无效。我在 VS 解决方案资源管理器中的 MyProject
的 Dependencies
节点下看到了那些黄色小三角形,因为该项目正在寻找缺少字符的路径中的 DLL。同样,当我构建项目时,我得到了一堆 The type or namespace name could not be found
错误,即使我仍然在我的目标中看到 Message
任务的输出。据推测,CreatePathProperty
目标在执行阶段是 运行,在 Reference
项在评估阶段加载失败后。
有没有办法让这样的设置工作?我已经尝试在 Target
元素中设置 BeforeTargets="Build"
,并在 Project
元素中设置 InitialTargets="CreateSomeProperty"
,但似乎没有任何效果。任何帮助将不胜感激!
Can an MSBuild Item use a Property set by a Target?
是的,如果你在 .net framework project with old csproj format
并且你想要的是 VS2017 中支持的场景(仅在 VS2017 中进行了测试),我相信这是可能的。
提示:
通常 msbuild
在执行您的自定义目标之前读取 Properties
和 Items
。所以我们应该使用 BeforeTargets="BeforeResolveReferences"
之类的东西来确保在这种情况下正确的顺序是 custom target runs=>create the property=>msbuild reads the info about references and the property
.
否则顺序(BeforeTargets="Build"
或什么时候顺序错误)应该是:Msbuild reads the info about references(now the property is not defined yet)=>the target runs and creates the property
.
解法: 将此脚本添加到 xx.csproj.
的底部 <!-- Make sure it executes before msbuild reads the ItemGroup above and loads the references -->
<Target Name="MyTest" BeforeTargets="BeforeResolveReferences">
<ItemGroup>
<!-- Define a TestFile to represent the file I read -->
<TestFile Include="D:\test.txt" />
</ItemGroup>
<!-- Pass the file to read to the ReadLinesFromFile task -->
<ReadLinesFromFile File="@(TestFile)">
<!--Create the Property that represents the normal hintpath(SomePath\DLLName.dll)-->
<Output TaskParameter="Lines" PropertyName="HintPathFromFile" />
</ReadLinesFromFile>
<!-- Output the HintPath in output log to check if the path is right -->
<Message Text="$(HintPathFromFile)" Importance="high" />
<ItemGroup>
<Reference Include="TestReference">
<!--It actually equals:<HintPath>D:\AssemblyFolder\TestReference.dll</HintPath>-->
<HintPath>$(HintPathFromFile)</HintPath>
</Reference>
</ItemGroup>
</Target>
另外:
我用 test.txt
文件做了测试,其内容是:
我不确定你的文件的实际内容(和格式),但如果你的文件中只有像 D:\AssemblyFolder\
这样的路径,你应该将 D:\AssemblyFolder\+YourAssemblyName.dll
传递给 <HintPath>
元数据。导致带有 hintpath
的 default reference
格式如下所示:
<Reference Include="ClassLibrary1">
<HintPath>path\ClassLibrary1.dll</HintPath>
</Reference>
注意路径格式!希望我的回答对您有所帮助:)
在 msbuild 中,static 项目无法根据设计依赖于 dynamic 属性。
接受的答案提供了一个解决方法:使用动态项目,这自然可以依赖于动态属性。但是动态项不会显示在 IDE.
中处理文件时,更 IDE 友好的方法是静态创建项目并在目标运行时更新它:
<!-- Static item definition -->
<ItemGroup>
<SomeItem Include="item_file" />
</ItemGroup>
<Target Name="...">
<!-- When the target runs, find the static item using Condition and change its properties -->
<ItemGroup>
<SomeItem Condition="'%(SomeItem.Identity)' == 'item_file'">
<SomeProperty>New Value</SomeProperty>
</SomeItem>
</ItemGroup>
</Target>
还有一个未解决的 msbuild 问题 (#889) 以支持为此改进的语法:
<Target Name="...">
<ItemGroup>
<!-- Update has the same syntax as Include -->
<SomeItem Update="item_file">
<SomeProperty>New Value</SomeProperty>
</SomeItem>
</ItemGroup>
</Target>