J'essaye d'exécuter msbuild
sur Azure Devops. À cause de cela, je ne peux pas utiliser la tâche MSBuild
fournie.
Lorsque j'utilise une tâche de ligne de commande, la commande n'est pas reconnue. Sur ma machine locale, je charge vcvarsall.bat
avant d'utiliser msbuild
. Mais je n'ai pas été incapable de trouver comment obtenir ce chemin dans Azure Devops. Ne semble pas non plus être une tâche de Développer l'invite de commande
pour Azue Devops.
Des idées sur la façon dont je peux utiliser msbuild
à partir d'une tâche de ligne de commande ou d'une tâche de script par lots? Utilisation de leur agent VS hébergé.
4 Réponses :
Si vous utilisez Hosted Agent 2017, vous pouvez exécuter msbuild.exe
à partir de la tâche de ligne de commande de cette manière:
Ligne de commande version 2:
Résultats:
Il doit s'agir de la version 1 de la tâche de ligne de commande? J'utilise la v2 car j'ai besoin d'appliquer une logique conditionnelle avant d'appeler msbuild. Ce chemin est-il également documenté? Ou est-ce un détail de mise en œuvre qui pourrait changer?
@Matt - c'est intéressant. Je cherchais des variables, mais je n'en ai trouvé aucune. Je pourrais essayer ça. J'ai également trouvé des indices lors de l'inspection d'un Build avec l'indicateur system.debug activé. La tâche MSBuild utilise un utilitaire pour rechercher et déterminer la version de MSBuild à utiliser.
La meilleure façon de le faire de manière prise en charge est d'utiliser vswhere
. Le bit de script suivant installera vswhere (en utilisant chocolatey), puis interrogera le registre du programme d'installation où msbuild peut être trouvé. Remplacez -latest
par une version plus spécifique si vous en avez besoin:
https://github.com/Microsoft/vswhere/releases/latest/download/vswhere.exe
Cela enregistrera le chemin de msbuild dans la variable d'environnement % msbuildpath% code> ainsi que la variable pipeline (pour cette étape)
$(msbuildpath)
.
Vous pouvez alors soit utiliser une deuxième tâche en ligne de commande et passer $ ( msbuildpath)
ou vous pouvez simplement appeler MsBuild à partir du même morceau de script mentionné ci-dessus en appelant:
%msbuildpath%
Cela garantira que votre script continuera de fonctionner, même si Microsoft met à jour leurs images et déplace certaines choses (ce qui arrive).
Vous pouvez également obtenir vswhere en utilisant wget
ou invoke-webrequest -outfile
depuis l'emplacement suivant:
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%"
Autre Des exemples de syntaxe vswhere
peuvent être trouvés sur le wiki du projet , y compris la syntaxe de PowerShell.
Si vous souhaitez voir comment la tâche Microsoft intégrée résout le chemin, toutes les tâches Azure Devops sont fournies en open source. Ce sont les fonctions de chemin a > vous souhaitez probablement revoir.
Voici la solution que j'ai proposée en utilisant uniquement des tâches de pipeline intégrées qui rendent le répertoire bin MSBuild disponible sur la variable d'environnement de chemin.
Créez une tâche PowerShell pour générer un projet MSBuild à capturer et à générer dans un fichier les variables qui vous intéressent (ex. MSBuildBinPath)
Script 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"
Définissez le répertoire de travail et toutes les variables en conséquence.
Capture d'écran des paramètres de tâche PowerShell :
Créez une tâche MSBuild pour exécuter le fichier de projet généré par la tâche précédente. Assurez-vous que la version de MSBuild est définie sur la version que vous souhaitez utiliser.
Capture d'écran des paramètres de tâche MSBuild :
Enfin, créez une autre tâche PowerShell qui analysera le fichier JSON des variables extraites et définira les variables d'environnement en conséquence.
Script 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
Pourquoi ne pouvez-vous pas utiliser la tâche msbuild fournie?
@Matt - parce que je dois l'invoquer avec différents paramètres de ligne de commande basés sur une autre logique conditionnelle dans mon système de construction.
Salut thomthom, la réponse ci-dessous a-t-elle résolu votre problème?