对于这个问题的一种解决方法是自定义MSBuild进程,以设置“目标框架模式程序集属性”文件(在问题中提到的文件的正确名称)将被创建的路径。
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
和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 文件中。
C:\Program Files (x86)\MSBuild\TeamCity\TeamCity.Incremental.targets(27, 9): error MSB4184: 表达式 "[System.IO.Path]::Combine( C:\Windows\system32\config\systemprofile\AppData\Local\Temp , .NETFramework,Version=v4.0.AssemblyAttributes.cs)" 无法评估。路径中有非法字符。
- Petrus Theron