在Azure Devops中从命令行任务运行MSBuild

在Azure Devops中从命令行任务运行MSBuild,msbuild,azure-devops,azure-pipelines,azure-devops-hosted-agent,Msbuild,Azure Devops,Azure Pipelines,Azure Devops Hosted Agent,我正试图在Azure Devops上执行msbuild。因此,我无法使用提供的MSBuild任务 使用命令行任务时,无法识别该命令。在使用msbuild之前,我在本地计算机上加载vcvvarsall.bat。但我还没有弄明白如何在Azure Devops中获得该路径。对于Azue Devops,似乎也不是一个Develop命令提示符任务 关于如何从命令行任务或批处理脚本任务中使用msbuild有什么想法吗?使用其托管VS代理。如果使用托管代理2017,可以通过以下方式从命令行任务运行msbuil

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

使用命令行任务时,无法识别该命令。在使用
msbuild
之前,我在本地计算机上加载
vcvvarsall.bat
。但我还没有弄明白如何在Azure Devops中获得该路径。对于Azue Devops,似乎也不是一个
Develop命令提示符任务


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

如果使用托管代理2017,可以通过以下方式从命令行任务运行
msbuild.exe

命令行版本1:

命令行版本2:

结果:


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

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升级了他们的图像并移动了一些东西(确实发生了)

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

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

其他,包括PowerShell的语法。

如果您有兴趣了解内置Microsoft任务如何解析路径,则所有Azure Devops任务都是开源的。这些是您可能需要查看的解决方案。

以下是我提出的仅使用内置管道任务的解决方案,它使MSBuild bin目录在path环境变量上可用

创建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
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任务设置屏幕截图:

下面是构建管道中任务顺序的屏幕截图


它必须是命令行任务的版本1?我使用v2是因为在调用msbuild之前需要应用一些条件逻辑。该路径是否也有文档记录?或者这是一个可能会改变的实现细节?@Matt-这很有趣。我在寻找变量,但没有找到任何变量。我可以试试。在检查启用system.debug标志的构建时,我还发现了一些线索。MSBuild任务使用一个实用程序来查找和确定要使用的MSBuild版本。为什么不能使用提供的MSBuild任务?@Matt-因为我需要根据生成系统中的其他条件逻辑使用不同的命令行参数调用它。您好,Thom,下面的答复是否解决了您的问题?