MSBuild:如何在定义自己的自定义属性时访问内置属性?



我有一个名为Common.targets的文件,定义如下:

<Project>
<PropertyGroup>
<TlbExpPath>"c:Program Files (x86)Microsoft SDKsWindowsv10.0AbinNETFX 4.6.1 Toolsx64tlbexp"</TlbExpPath>
<TlbOutPath>"$(OutDir)..TLB$(TargetName).tlb"</TlbOutPath>
</PropertyGroup>
<Target Name="TlbExp" AfterTargets="CopyFilesToOutputDirectory" Inputs="$(TargetPath)" Outputs="$(TlbOutPath)">
<Exec Command='$(TlbExpPath) "$(TargetPath)" /nologo /win64 /out:$(TlbOutPath) /verbose' />
</Target>
</Project>

当我检查TlbOutPath属性的输出时,它看起来像:

"..TLB.tlb"

显然,$(OutDir)$(TargetName)PropertyGroup中使用时不会产生任何结果。我不知道为什么。如何使这些路径/值可重用,同时在定义内置属性时仍有权访问内置属性?

我正在使用与Visual Studio 2019捆绑在一起的MSBuild。我在实际.csproj项目中添加一个Import元素,以在我需要的地方包含此目标。csproj项目使用SDK格式进行项目,例如<Project Sdk="Microsoft.NET.Sdk">.

下面是导入的示例:

<Project Sdk="Microsoft.NET.Sdk">
<!-- etc -->
<ItemGroup>
<Reference Include="Microsoft.CSharp" />
<!-- etc -->
</ItemGroup>
<Import Project="$(RepositoryRoot)Common.targets" />
</Project>

MSBuild:如何在定义自己的属性时访问内置属性 自定义属性?

这在新的 sdk 格式项目中是一个相当大的问题。我已经对其进行了测试,并遇到了与您所说的相同的问题,这让我非常困扰。像$(OutDir)一样,$(TargetName)$(OutputPath)$(TargetPath)和其他一些常见的系统属性不能在新属性中使用,而$(Configuration)$(AssemblyName)运行良好。

不仅是我们,其他人也面临着同样的问题。请参阅此线程。

对于传统的旧 csproj 格式项目,以这种方式使用这些属性没有问题,但在新的 SDK 格式项目中,不可能将一些通用属性(如$(OutDir)$(TargetName)$(TargetPath)(分配给新属性。众所周知,大多数公共属性都是在Microsoft.Common.props文件(旧的csproj格式(中定义的,这与没有此类文件的新sdk格式项目有很大不同。

为了得到答案,我已经向DC论坛报告了这个问题。看到这里。您可以输入此链接并添加任何详细注释来描述此问题。任何对这个问题感兴趣的人也会投票,以便它得到更多的Microsoft工作人员的关注。所有这些努力都将加快并得到最终答案。

这个过程可能需要一段时间,或者你可以试试我的建议。

建议

1(您可以在Common.targets文件中自定义此属性$(OutDir),并使用$(TargetFramework)而不是$(TargetName),因为$(TargetFramework)是在xxxx.csproj文件中定义的。

<Project>
<PropertyGroup>
<OutDir>bin$(Configuration)$(TargetFramework)$(AssemblyName)</OutDir>
<TlbExpPath>"c:Program Files (x86)Microsoft SDKsWindowsv10.0AbinNETFX 4.6.1 Toolsx64tlbexp"</TlbExpPath>
<TlbOutPath>"$(OutDir)..TLB$(TargetName).tlb"</TlbOutPath>
<TargetPath>xxxxxxxx.dll(exe)</TargetPath>--------the absolute path of the output file
</PropertyGroup>
<Target Name="TlbExp" AfterTargets="CopyFilesToOutputDirectory" Inputs="$(TargetPath)" Outputs="$(TlbOutPath)">
<Exec Command='$(TlbExpPath) "$(TargetPath)" /nologo /win64 /out:$(TlbOutPath) /verbose' />
</Target>
</Project>

2(使用 Directory.Build.targets 文件,而不是自定义目标文件。

A(您应该在项目文件夹下添加一个名为Directory.Build.targets的文件(它必须命名为 this 并具有自己的规则才能导入xxx.csproj(。

B(Common.targets的内容添加到其中而不进行任何更改,然后直接构建您的项目。Directory.Build.targets将在生成时自动导入到项目中。

此函数运行良好,不会丢失任何属性。但是,我仍然在烦恼它为什么有效。

结论

我认为#2更适合您,更容易实现目标。

最新更新