【问题标题】:Run MSBuild from Command Line task in Azure Devops从 Azure Devops 中的命令行任务运行 MSBuild
【发布时间】:2019-07-25 22:30:03
【问题描述】:

我正在尝试在 Azure Devops 上执行 msbuild。因此,我无法使用提供的MSBuild 任务。

当我使用命令行任务时,无法识别该命令。在我的本地机器上,我在使用msbuild 之前加载了vcvarsall.bat。但我一直无法弄清楚如何在 Azure Devops 中获得该路径。似乎也不是 Azue Devops 的 Develop Command Prompt 任务。

关于如何在命令行任务或批处理脚本任务中使用msbuild 有什么想法吗?使用他们的托管 VS 代理。

【问题讨论】:

  • 为什么不能使用提供的msbuild任务?
  • @Matt - 因为我需要根据构建系统中的一些其他条件逻辑使用不同的命令行参数调用它。
  • 您好 thomthom,下面的回复解决了您的问题吗?

标签: msbuild azure-devops azure-pipelines azure-devops-hosted-agent


【解决方案1】:

这是我提出的仅使用内置管道任务的解决方案,它使 MSBuild bin 目录在路径环境变量中可用。

创建一个 PowerShell 任务来生成一个 MSBuild 项目,以捕获您感兴趣的变量并将其输出到文件中(例如 MSBuildBinPath)

PowerShell 脚本

"<Project DefaultTargets=`"DetectMsBuild`">
    <ItemGroup>        
        <OutFile Include=`"`$(MsBuildDetectionFile)`" />
        <OutFile Condition=`"'`$(OutFile)' == ''`" Include=`"msbuildInfo.json`" />
    </ItemGroup>

    <Target Name=`"DetectMsBuild`">
        <PropertyGroup>
            <MsBuildPaths>
[{
    `"Name`": `"BinPath`",
    `"Value`": `"`$(MSBuildBinPath.Replace('\', '\\'))`"
}]
            </MsBuildPaths>
        </PropertyGroup>

        <WriteLinesToFile
            File=`"@(Outfile)`"
            Lines=`"`$(MsBuildPaths)`"
            Overwrite=`"true`"
            Encoding=`"UTF-8`" />
    </Target>
</Project>" | Out-File -FilePath "msbuilddetect.proj" -Encoding utf8

相应地设置工作目录和任何变量。

PowerShell 任务设置截图

创建一个 MSBuild 任务来运行上一个任务生成的项目文件。确保将 MSBuild 版本设置为您要使用的版本。

MSBuild 任务设置截图

最后,创建另一个 PowerShell 任务,该任务将解析​​提取的变量的输出 JSON 文件并相应地设置环境变量。

PowerShell 脚本

Write-Host "Current path: $($env.Path)`n`n"

$msBuildVariables = Get-Content -Path msbuildInfo.json | ConvertFrom-Json

$Path = "$($msBuildVariables[0].Value);$($env:Path)"
Write-Host "##vso[task.setvariable variable=Path;]$Path"

PowerShell 任务设置截图

这是构建管道中任务顺序的屏幕截图。

【讨论】:

    【解决方案2】:

    以受支持的方式执行此操作的最佳方法是使用vswhere。以下脚本将安装 vswhere(使用巧克力),然后查询可以找到 msbuild 的安装程序注册表。如果需要,请将 -latest 替换为更具体的版本:

    choco install vswhere
    for /f "tokens=*" %%i in ('vswhere -latest -requires Microsoft.Component.MSBuild -find MSBuild\**\Bin\MSBuild.exe -nologo') do set msbuildpath="%%i"
    
    echo "##vso[task.setvariable variable=msbuildpath]%msbuildpath%"
    

    这会将 msbuild 的路径保存到环境变量 %msbuildpath% 以及管道变量(对于这个阶段)$(msbuildpath)

    然后您可以使用第二个运行命令行任务并传入$(msbuildpath),或者您可以简单地从上面提到的同一段脚本中调用 MsBuild,方法是调用:

    %msbuildpath%
    

    这将确保您的脚本将继续工作,即使 Microsoft 升级了他们的图像并移动了一些东西(确实发生了)。

    您还可以使用wgetinvoke-webrequest -outfile 从以下位置获取vswhere:

    https://github.com/Microsoft/vswhere/releases/latest/download/vswhere.exe
    

    其他samples for vswhere syntax can be found on the project wiki,包括PowerShell的语法。

    【讨论】:

      【解决方案3】:

      如果您有兴趣了解内置 Microsoft 任务如何解析路径,所有 Azure Devops 任务都是开源的。这些是您可能想查看的path functions

      【讨论】:

        【解决方案4】:

        如果您使用 Hosted Agent 2017,您可以通过以下方式从命令行任务运行 msbuild.exe

        命令行版本 1:

        命令行版本 2:

        结果:

        【讨论】:

        • 它必须是命令行任务的版本 1?我正在使用 v2,因为我需要在调用 msbuild 之前应用一些条件逻辑。该路径是否也记录在案?或者这是一个可能会改变的实现细节?
        • @Matt - 这很有趣。我正在寻找变量,但我没有找到任何变量。我可以试试。在检查带有 system.debug 标志的构建时,我还发现了一些线索。 MSBuild 任务使用一个实用程序来查找和确定要使用的 MSBuild 版本。
        猜你喜欢
        • 2019-03-30
        • 2021-09-27
        • 2020-10-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-04-02
        • 2017-06-26
        相关资源
        最近更新 更多