在Azure DevOps中设置VSBuild任务以解决msbuildArgs被忽略的问题

485次阅读
没有评论

问题描述

在更新到C# 10后,我必须更新Azure DevOps管道以使用以下配置:

pool:
  vmImage: 'windows-2022'

然后出现了以下错误:

C:\Program Files\dotnet\sdk\6.0.200\Sdks\Microsoft.NET.Sdk\targets\Microsoft.PackageDependencyResolution.targets(267,5): Error NETSDK1047: Assets file 'D:\a\1\s\src\MyProject\obj\project.assets.json' doesn't have a target for 'net461/win7-x64'. Ensure that restore has run and that you have included 'net461' in the TargetFrameworks for your project. You may also need to include 'win7-x64' in your project's RuntimeIdentifiers.

我想为我的net461的WPF应用程序添加RuntimeIdentifier,但似乎只有Azure DevOps需要这个,我的本地机器上不需要。我希望只在管道中设置这个属性。所以我进入了管道的YAML文件并稍微修改了一下(添加了msbuildArgs的最后一个参数):

- task: VSBuild@1
  displayName: 'Build App (net461)'
  inputs:
    solution: '$(wpfCsproj)'
    platform: '$(buildPlatform)'
    configuration: '$(buildConfiguration)'
    msbuildArgs: '/p:OutputPath=$(buildOutputAdminGui) /p:TargetFramework="net461" /p:RuntimeIdentifier="win7-x64"'

但是似乎这个参数被完全忽略了,错误仍然存在。当我在csproj中手动定义属性时,它可以工作。

然而,如果我想这样做:

<PropertyGroup Condition="'$(IsOnAzure)' == 'true'">
    <RuntimeIdentifier>win7-x64</RuntimeIdentifier>
</PropertyGroup>

并在管道中以类似的方式添加/p:IsOnAzure="true",也不起作用。似乎只有一些特定的MSBuild属性可以在VSBuild任务中这样设置…。

我怎么才能知道我的构建任务当前是否在Azure DevOps管道环境中执行,以及如何设置不被忽略的msbuildArgs呢?也许是因为C# 10不支持.NET Framework,但是该项目在Visual Studio 2022 Professional中可以顺利构建,添加RuntimeIdentifier也可以使管道正常工作。只是奇怪的是,在之前不需要的情况下,现在突然需要它。

解决方案

请注意以下操作可能因版本差异或特定环境而异,进行任何更改前请确保备份代码和管道配置。

方案1:使用条件语句

您可以使用Azure DevOps的预定义变量来判断当前构建是否在Azure DevOps管道环境中执行。然后,您可以根据需要添加msbuildArgs

以下是一个示例的YAML片段,演示了如何根据Azure DevOps的环境来设置msbuildArgs

- task: VSBuild@1
  displayName: 'Build App (net461)'
  inputs:
    solution: '$(wpfCsproj)'
    platform: '$(buildPlatform)'
    configuration: '$(buildConfiguration)'
    msbuildArgs: $(msbuildArgs) /p:TargetFramework="net461"
    condition: eq(variables['Agent.OS'], 'Windows_NT')  # 判断是否在Windows环境下

在这个示例中,我们使用了condition属性来判断构建是否在Windows环境下运行。如果是的话,就会使用msbuildArgs中的参数。

方案2:使用脚本任务

如果您希望更灵活地控制构建过程,您可以使用脚本任务来动态生成msbuildArgs。这允许您根据需要在管道中设置不同的参数。

以下是一个示例的YAML片段,演示了如何使用脚本任务来设置msbuildArgs

- powershell: |
    $runtimeIdentifier = "win7-x64"  # 设置RuntimeIdentifier
    $msbuildArgs = "/p:TargetFramework='net461' /p:RuntimeIdentifier='$runtimeIdentifier'"
    Write-Host "##vso[task.setvariable variable=msbuildArgs]$msbuildArgs"
  displayName: 'Set msbuildArgs'
  condition: eq(variables['Agent.OS'], 'Windows_NT')  # 判断是否在Windows环境下

- task: VSBuild@1
  displayName: 'Build App (net461)'
  inputs:
    solution: '$(wpfCsproj)'
    platform: '$(buildPlatform)'
    configuration: '$(buildConfiguration)'
    msbuildArgs: $(msbuildArgs)
    condition: eq(variables['Agent.OS'], 'Windows_NT')

在这个示例中,我们首先使用PowerShell任务设置msbuildArgs的值,并将其存储在变量中。然后,在VSBuild任务中,我们使用这个变量作为msbuildArgs的值。

无论您选择哪种方案,都可以根据需要动态设置msbuildArgs,以解决Azure DevOps中msbuildArgs被忽略的问题。

请注意,根据特定情况,您可能需要根据您的需求进行进一步的调整和修改。

正文完