我有一个名为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更适合您,更容易实现目标。