此问题的解决方法是自定义 MSBuild 过程以设置将创建“目标框架 Moniker 程序集属性”文件(问题中提到的文件的正确名称)的路径。
该TargetFrameworkMonikerAssemblyAttributesPath
属性在 Microsoft.Common.targets 中定义,确定应在何处创建文件。通过覆盖此属性,可以更改位置以使用不同的位置。
这是一个可用于实现合适替换的脚本:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<PrepareForBuildDependsOn>
$(PrepareForBuildDependsOn);
_SetTargetFrameworkMonikerAssemblyAttributesPath
</PrepareForBuildDependsOn>
</PropertyGroup>
<Target
Name="_SetTargetFrameworkMonikerAssemblyAttributesPath"
Condition="'$(TEAMCITY_VERSION)' != ''">
<PropertyGroup>
<TargetFrameworkMonikerAssemblyAttributesDir
Condition="'$(TargetFrameworkMonikerAssemblyAttributesDir)' == ''">
$([MSBuild]::GetRegistryValue("HKEY_CURRENT_USER\Environment", "TMP"))
</TargetFrameworkMonikerAssemblyAttributesDir>
<TargetFrameworkMonikerAssemblyAttributesDir
Condition="'$(TargetFrameworkMonikerAssemblyAttributesDir)' == ''">
$([MSBuild]::GetRegistryValue("HKEY_CURRENT_USER\Environment", "TEMP"))
</TargetFrameworkMonikerAssemblyAttributesDir>
<TargetFrameworkMonikerAssemblyAttributesDir
Condition="'$(TargetFrameworkMonikerAssemblyAttributesDir)' == ''">
$(USERPROFILE)
</TargetFrameworkMonikerAssemblyAttributesDir>
<TargetFrameworkMonikerAssemblyAttributesDir
Condition="'$(TargetFrameworkMonikerAssemblyAttributesDir)' == ''">
$([System.IO.Path]::Combine('$(WINDIR)', 'Temp'))
</TargetFrameworkMonikerAssemblyAttributesDir>
<TargetFrameworkMonikerAssemblyAttributesPath>
$([System.IO.Path]::Combine('$(TargetFrameworkMonikerAssemblyAttributesDir)','$(TargetFrameworkMoniker).AssemblyAttributes$(DefaultLanguageSourceExtension)'))
</TargetFrameworkMonikerAssemblyAttributesPath>
</PropertyGroup>
<Message Text="Target Framework Moniker Assembly Attributes path is "$(TargetFrameworkMonikerAssemblyAttributesPath)"" Importance="low" />
</Target>
只有在指定为属性时才会执行目标TEAMCITY_VERSION
,这应该是在 TeamCity 代理执行构建时。
注意:的每个子元素都PropertyGroup
应该在一行上。它们分布在多行中以增加此处的可读性,但额外的换行符会导致脚本失败。
当目标运行时,它会尝试根据注册表中定义的用户环境变量构建合适的路径,首先查找TMP
and TEMP
,然后返回到用户的配置文件文件夹,最后返回C:\Windows\Temp
目录。这与 System.Path.GetTempPath() 记录的顺序相匹配,并且应该导致行为匹配 TeamCity 之外的 MSBuild 执行。
这应该保存为系统某处的 .targets 文件,并使用<Import>
元素导入到 TeamCity 服务器正在构建的项目的 .csproj 文件中。我在我的 MSBuild 扩展目录 ( C:\Program Files\MSBuild\
) 下添加了脚本,并通过添加以下导入元素来引用它:
<Import Project="$(MSBuildExtensionsPath)\TeamCity\TeamCity.Incremental.targets" />
Import 元素的位置/顺序无关紧要,但我建议将它包含在<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
应该出现在每个 .csproj 文件中的之后。