Azure DevOps PipelinesでVS2015 / VS2022の同時ビルド #3

前回の投稿でAzure Pipelines agentを使ってVS2015とVS2022のVC++プロジェクトの両方を含むソリューションをビルドできる方法を説明しました。その後、Visual Studioのバージョンが上がるとうまく動作しないことがあることがわかりました。今回は、バージョン変更にも影響しないスクリプトに更新します。

Azure pipelines agentのイメージのVisual Studioのバージョン

マイクロソフトが用意してくれているAzure pipelines agentのWindowsのOSイメージには、Visual Studioがインストールされています。

そのインストールされているVisual Studioのメジャーバージョンは、OSイメージ毎に決まっています。

imageOSVisual StudioVisual Studioのコンポーネント
Microsoft.VisualStudio.Component.VC.140
windows-2019Microsoft Windows Server 2019 DatacenterVisual Studio Enterprise 2019インストール済み
(Toolset vs2015 (vc140)はビルドできる)
windows-2022Microsoft Windows Server 2022 DatacenterVisual Studio Enterprise 2022未インストール
(Toolset vs2015 (vc140)はビルドできない)
windows-latestwindows-2022と同じwindows-2022と同じwindows-2022と同じ

上記の表のように2022年10月現在では、Windows-2019のイメージならVisual Studio 2019 (16.y.z系)で、Windows-2022のイメージならVisual Studio 2022 (17.y.z系)です。

Visual Studioのバージョンと更新

Visual Studioの内部的なビルド番号は、17.3.32929.385のように、第3パート目、第4パート目が覚えにくい複雑な番号です。しかし、Visual Studioの表示用のバージョンは、Version x.y.zの形式で表現され、zに関しても、1からの連番となり、わかりやすいバージョン番号です。

たとえば、2022年10月現在では、Visual Studio 2022の最新バージョンは17.3.6となります。

Visual Studioは定期的に更新されています。たとえば、Visual Studio 2022 Update 3 (17.3)であれば以下のように更新されてます。

バージョン番号
(x.y.z)
ビルド番号リリース日
17.3.017.3.32804.4672022年8月9日
17.3.117.3.32811.3152022年8月16日
17.3.217.3.32819.1012022年8月23日
17.3.317.3.32825.2482022年8月30日
17.3.417.3.32901.2152022年9月13日
17.3.517.3.32922.5452022年9月27日
17.3.617.3.32929.3852022年10月11日
Visual Studio 2022 Update 3の更新履歴

バージョン番号のzの部分に相当するマイナーマイナーバージョンは、1週間から2週間くらいで更新されています。

Azure pipelines agentのイメージのVisual Studioのバージョンの更新

マイクロソフトが用意しているAzure pipelines agentのOSイメージ内のVisual Studioも定期的に更新されています。17.3.0から17.3.6までのOSイメージの更新日を列挙すると以下の通りです。

バージョン番号
(x.y.z)
ビルド番号Visual Studio 2022の
リリース日
Azure pipelines agentの
OSイメージの更新日
17.3.017.3.32804.4672022年8月9日2022年8月16日
17.3.117.3.32811.3152022年8月16日2022年8月17日
17.3.217.3.32819.1012022年8月23日2022年8月30日
17.3.317.3.32825.2482022年8月30日2022年9月7日
17.3.417.3.32901.2152022年9月13日2022年9月21日
17.3.517.3.32922.5452022年9月27日2022年10月5日
17.3.617.3.32929.3852022年10月11日2022年10月14日
Azure Pipelines agentのOSイメージの更新履歴

Visual Studioの更新版がリリースされてからおおよそ1週間後までには、OSイメージ内のVisual Studioが更新されています。

前回のVisual Studioのコンポーネント追加のスクリプト

このVisual Studioの更新時期のずれが、前回に提示した「Visual Studioのコンポーネント追加」スクリプトに影響がありました。

スクリプトでは、コンポーネントを追加するためのインストーラーとしてvs_enterprise.exeをネットワークからダウンロードします。このダウンロードに使用しているURLが、

https://aka.ms/vs/17/release/vs_enterprise.exe

となります。このURLでは、Visual Studio 2022 (バージョン17)の最新版のインストーラーをダウンロードできます。

ダウンロードしたインストーラーを使って単純にコンポーネントを追加します。すると、ダウンロードしたインストーラーのバージョンとシステムにインストールされているVisual Studioのバージョンが一致しないため、コンポーネントの追加が失敗します。

たとえば、上記の表を参考に2022年10月12日の時点での状態を考えてみます。この時点では、

  • ダウンロードできるVisual Studioインストーラー(vs_enterprise.exe)のバージョンは17.3.6
  • OSイメージ内のVisual Studioのバージョンは17.3.5

となります。両者のバージョンは、17.3.6と17.3.5であり、バージョンが異なるのです。

そのため、単純なコンポーネントの追加では、エラーとなり失敗します。

これは、前回提示した「Visual Studioのコンポーネント追加」スクリプトは、Visual Studioの更新のタイミングによっては、失敗すること意味します。

実際、そのスクリプトを使って、Azure pipelines agentでの上記の日のパイプラインビルドは失敗しました。

Visual Studioインストーラーの各バージョンのダウンロードリンク

両者のバージョンを一致させれば、コンポーネントの追加はできます。実際、Visual Studioインストーラーの各バージョンのダウンロードリンクもマイクロソフトのサイトに列挙されています。たとえば、Visual Studio 2022であれば、ここ(Visual Studio 2022 リリース履歴)に列挙されています。

このURLを確認すると以下の表となります。

バージョンVisual Studio 2022のvs_enterprise.exeのダウンロードリンク
17.3.0https://download.visualstudio.microsoft.com/download/pr/9e57b328-71ac-4bdd-bb2b-bdfb71417bbb/6582df36e8b1eaff676b4342ecc4e2c6c5ea495a24898f750260186fca8724ed/vs_Enterprise.exe
17.3.1https://download.visualstudio.microsoft.com/download/pr/af9ede5a-5bbf-435e-9cdc-4017b67d3704/f40151eadfd6dcc26f6b0d961099181f047202a2160dcade5a963d45882ee254/vs_Enterprise.exe
17.3.2https://download.visualstudio.microsoft.com/download/pr/27a23027-9958-4bba-8bc2-a96997f86ad6/264de14cc89d7e2bfbdafaf53fd586bc18ef3ef4a29c1c201a028fd0e769321a/vs_Enterprise.exe
17.3.3https://download.visualstudio.microsoft.com/download/pr/5fa6fcf5-8e43-4a4c-9ccc-ed024ab2585a/b16a76a934bf339d6c2b1321e7092a1ebec92b049b1a5bd0b9c95c09b18e2e7d/vs_Enterprise.exe
17.3.4https://download.visualstudio.microsoft.com/download/pr/8106c1cc-df87-4854-8865-3b46bef5867c/59ad14eb280fcdafbdbcf66219ad05ad11d114611526ab8597ef338fadda172e/vs_Enterprise.exe
17.3.5https://download.visualstudio.microsoft.com/download/pr/21ed51cb-52a5-454f-87b6-75a88ef54361/4240cd23dfdeb70c3cc398678d85f9958f3bcb1d040c40ac18db61ad2d2ba3ad/vs_Enterprise.exe
17.3.6https://download.visualstudio.microsoft.com/download/pr/5c9aef4f-a79b-4b72-b379-14273860b285/cd049375d7c872eb38e84b2c52d41eb564c79136cb7fc00c0ce2c311d5bd3f9e/vs_Enterprise.exe
Visual Studio 2022 Enterpriseのインストーラーの各バージョンのURL

バージョン番号とは無関係な規則性のないURLとなっています。そのため、バージョン番号からダウンロードURLをスクリプトで自動生成することはできません。

これらのURLをスクリプトに埋め込んだ場合、Visual Studio 2022の更新の間隔(1週間から2週間くらい)に合わせて、スクリプトを更新する必要が出てしまします。

これでは、頻繁に修正が必要なメンテナンス性が悪いスクリプトとなってしまいます。

最新版のVisual Studioインストーラーで古いコンポーネントをインストールする

どうにか頻繁な更新を必要としないメンテナンス性のよいスクリプトのままにできないか検討・調査しました。

すると、最新版のVisual Studioインストーラーを使って、過去のバージョンのVisual Studioのコンポーネントを追加する方法を見つけることができました。

具合的には、Visual Studio インストーラーの --InstallPath オプションを使う方法です。

前回のスクリプトでは、以下のようなコマンドラインでコンポーネントを追加しました。

vs_enterprise.exe -q --wait --add Microsoft.VisualStudio.Component.VC.140

この場合、システムにインストールされているVisual Studioのバージョンとインストーラーであるvs_enterprise.exeのバージョンが一致していないと、コンポーネントの追加は失敗します。

しかし、--InstallPath オプションを使い、以下のようなコマンドラインでコンポーネントを追加することができます。

vs_enterprise.exe modify -q --wait --add Microsoft.VisualStudio.Component.VC.140 --InstallPath "C:\Program Files\Microsoft Visual Studio\2022\Enterprise"

--InstallPath オプションを追加すると、最新のVisual Studioインストーラーを使ったとしても、指定したパスにインストールされているVisual Studioのバージョンに一致するコンポーネントを追加できます。

--InstallPath オプションを使うと、常に最新のVisual Studioインストーラーを使うことができます。

Visual Studioのインストール情報の取得

ただ、--InstallPath オプションを使う場合、Visual Studioのインストールフォルダーのパスが必要となります。多くの場合は、インストール時の既定のパスにインストールされているので、それを想定してもよいかもしれません。しかし、Visual Studioのインストーラーではインストール場所を変更できるUIを持っており、他人が作成するOSイメージの場合、既定のパスにインストールされている保証はありません。

そのため、スクリプトでシステムからVisual Studio 2022のインストールパスを取得する必要があります。

インストール済みのVisual Studio 2022のインストールパスを取得できないか、調査した結果、このインストールパスを取得するために、vswhere.exeというコマンドが使えることがわかりました。

vswhere.exeは、以下のいずれかにインストールされています。

  • %ProgramFiles%\Microsoft Visual Studio\Installer\vswhere.exe
  • %ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe

このパスは、vswhere.exeのインストール時にユーザーが変更することはできません。そのため、スクリプトでは、上記の二つのパスのどちらかにある前提で実装することで問題ありません。

このコマンドを引数なしで実行すると、インストール済みのVisual Studioの情報がすべて表示されます。

下記は、実際に実行した例です。

C:\>"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" -latest

Visual Studio Locator version 3.0.3+45247720e1 [query version 3.4.1128.26111]
Copyright (C) Microsoft Corporation. All rights reserved.

instanceId: d86afddf
installDate: 2021/10/20 11:54:20
installationName: VisualStudio/17.3.6+32929.385
installationPath: C:\Program Files\Microsoft Visual Studio\2022\Enterprise
installationVersion: 17.3.32929.385
productId: Microsoft.VisualStudio.Product.Enterprise
productPath: C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\devenv.exe
state: 4294967295
isComplete: 1
isLaunchable: 1
isPrerelease: 0
isRebootRequired: 0
displayName: Visual Studio Enterprise 2022
description: あらゆる規模のチーム向けのスケーラブルなエンドツーエンド ソリューション
channelId: VisualStudio.17.Release
channelUri: https://aka.ms/vs/17/release/channel
enginePath: C:\Program Files (x86)\Microsoft Visual Studio\Installer\resources\app\ServiceHub\Services\Microsoft.VisualStudio.Setup.Service
installedChannelId: VisualStudio.17.Release
installedChannelUri: https://aka.ms/vs/17/release/channel
releaseNotes: https://docs.microsoft.com/en-us/visualstudio/releases/2022/release-notes-v17.3#17.3.6
thirdPartyNotices: https://go.microsoft.com/fwlink/?LinkId=661288
updateDate: 2022-10-16T14:39:55.0887699Z
catalog_buildBranch: d17.3
catalog_buildVersion: 17.3.32929.385
catalog_id: VisualStudio/17.3.6+32929.385
catalog_localBuild: build-lab
catalog_manifestName: VisualStudio
catalog_manifestType: installer
catalog_productDisplayVersion: 17.3.6
catalog_productLine: Dev17
catalog_productLineVersion: 2022
catalog_productMilestone: RTW
catalog_productMilestoneIsPreRelease: False
catalog_productName: Visual Studio
catalog_productPatchVersion: 6
catalog_productPreReleaseMilestoneSuffix: 1.0
catalog_productSemanticVersion: 17.3.6+32929.385
catalog_requiredEngineVersion: 3.3.2185.63263
properties_campaignId: 2104554884.1570635532
properties_channelManifestId: VisualStudio.17.Release/17.3.6+32929.385
properties_nickname:
properties_setupEngineFilePath: C:\Program Files (x86)\Microsoft Visual Studio\Installer\setup.exe

このように、vswhere.exeを使うと、Visual Studioのインストール情報が取得できます。この中の情報から、スクリプトの実装に必要な情報を利用します。

インストールパスの一覧の取得

インストールパスを取得するには-property installationPathオプションを使います。

実際にシステムにインストールされているVisual Studioのインストールパスの一覧は、以下で取得できます。

"%ProgramFiles%\Microsoft Visual Studio\Installer\vswhere.exe" -property installationPath

C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise
C:\Program Files\Microsoft Visual Studio\2022\Enterprise
C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise

インストールバージョンの一覧の取得

また、同様に、インストールバージョンを取得するには-property catalog_productDisplayVersionオプションを使います。

実際にシステムにインストールされているVisual Studioのバージョンの一覧は、以下で取得できます。

"%ProgramFiles%\Microsoft Visual Studio\Installer\vswhere.exe" -property property catalog_productDisplayVersion

15.9.50
17.3.6
16.11.20

情報取得のバージョン限定

上記例では、Visual Studioが複数インストールされていた場合、すべてのバージョンのVisual Studioの情報が取得できます。

情報を取得するVisual Studioのバージョンを限定したい場合は、-versionオプションが使えます。例えば、Visual Studio 2022 (17)に限定して Visual Studio 2022 インストールパスを取得するには、以下のコマンドで可能です。

"%ProgramFiles%\Microsoft Visual Studio\Installer\vswhere.exe" -property installationPath -version [17,17.9999]

17.3.6

インストールされているVisual Studioの最新バージョンの情報を取得したい場合は、-latestオプションが使えます。

"%ProgramFiles%\Microsoft Visual Studio\Installer\vswhere.exe" -property installationPath -latest

17.3.6

コンポーネントの追加するスクリプトの最終版

今回、vswhere.exeでいろいろな情報を取得できることがわかったため、最終的には、

  • Visual Studioの最新バージョンの自動判定
  • Visual Studioのエディション(Enterprise/Professional/Community)の自動判定

の機能も追加しました。

前者は、SET VS_MAJOR_VERSION=LATESTのように、環境変数VS_MAJOR_VERSIONLATESTを設定すると、自動的にシステムにインストールされている最新バージョンのVisual Studioを対象とします。環境変数VS_MAJOR_VERSIONにVisual Studioのメジャーバージョンを明示的に設定(たとえば、16や17など)すると、そのバージョンのVisual Studioを前提に動作します。

後者は、マイクロソフトが用意したAzure pipelines agentのOSイメージでは、Visual Studioは、必ずEnterprise版が使われています。しかし、他の環境では、Professionalを利用していることも多いと思います。このスクリプトをそのような環境でもそのまま利用できるようにするため、エディションの自動判定機能を追加しました。環境変数VS_PRODUCT_IDに値を設定しないとインストールされているVisual Studioからエディションを自動的に決定します。環境変数VS_PRODUCT_IDにProductIdを明示的に設定(たとえば、Microsoft.VisualStudio.Product.Enterpriseなど)すると、そのエディションを前提に動作します。

最終的なスクリプトは以下の通りです。

@echo off
REM Copyright 2022, 2023 nishy software
REM The MIT License (MIT)

SET VS_MAJOR_VERSION=LATEST
REM SET VS_MAJOR_VERSION=16

SET ADD_COMPONENTS=--add Microsoft.VisualStudio.Component.VC.140

SET VS_INSTALLED_PATH=
SET VS_PRODUCT_ID=
cd %TEMP%


ECHO VS_MAJOR_VERSION=%VS_MAJOR_VERSION%
ECHO It was specified to use the version %VS_MAJOR_VERSION% of Visual Studio.

SET VSWHERE=%ProgramW6432%\Microsoft Visual Studio\Installer\vswhere.exe
IF not exist "%VSWHERE%" SET VSWHERE=%ProgramFiles%\Microsoft Visual Studio\Installer\vswhere.exe
IF not exist "%VSWHERE%" SET VSWHERE=%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe
IF not exist "%VSWHERE%" SET VSWHERE=

IF not "x-%VSWHERE%" == "x-" (
ECHO -
ECHO This system has the following versions of Visual Studio
"%VSWHERE%" -property catalog_productDisplayVersion
)

IF "x-%VS_MAJOR_VERSION%" == "x-LATEST" (
IF not "x-%VSWHERE%" == "x-" (
for /F "usebackq delims=,." %%A in (`"%VSWHERE%" -property catalog_productDisplayVersion -latest`) do SET VS_MAJOR_VERSION=%%A
)
)

IF "x-%VS_MAJOR_VERSION%" == "x-LATEST" (
ECHO Error: Could not find the latest version of Visual Stduio
exit /B -1
)

IF "x-%VS_INSTALLED_PATH%" == "x-" (
IF not "x-%VSWHERE%" == "x-" (
for /F "usebackq tokens=*" %%A in (`"%VSWHERE%" -property installationPath -version [%VS_MAJOR_VERSION%^,%VS_MAJOR_VERSION%.9999]`) do SET VS_INSTALLED_PATH=%%A
)
)

IF "x-%VS_INSTALLED_PATH%" == "x-" (
ECHO Error: Could not find the installed folder of Visual Stduio
exit /B -1
)

IF "x-%VS_PRODUCT_ID%" == "x-" (
IF not "x-%VSWHERE%" == "x-" (
for /F "usebackq" %%A in (`"%VSWHERE%" -property productId -version [%VS_MAJOR_VERSION%^,%VS_MAJOR_VERSION%.9999]`) do SET VS_PRODUCT_ID=%%A
)
)

IF "x-%VS_PRODUCT_ID%" == "x-" (
ECHO Error: Could not determine the edition of Visual Stduio
exit /B -1
)

SET VS_INSTALLER_EXE=
IF "x-%VS_PRODUCT_ID%" == "x-Microsoft.VisualStudio.Product.BuildTools" SET VS_INSTALLER_EXE=vs_buildtools.exe
IF "x-%VS_PRODUCT_ID%" == "x-Microsoft.VisualStudio.Product.Community" SET VS_INSTALLER_EXE=vs_community.exe
IF "x-%VS_PRODUCT_ID%" == "x-Microsoft.VisualStudio.Product.Professional" SET VS_INSTALLER_EXE=vs_professional.exe
IF "x-%VS_PRODUCT_ID%" == "x-Microsoft.VisualStudio.Product.Enterprise" SET VS_INSTALLER_EXE=vs_enterprise.exe
IF "x-%VS_INSTALLER_EXE%" == "x-" (
ECHO Error: Could not determine the name of the Visual Studio installer [ProductId=%VS_PRODUCT_ID%]
exit /B -1
)

ECHO -
ECHO Use Visual Stduio %VS_MAJOR_VERSION% (%VS_PRODUCT_ID%, %VS_INSTALLED_PATH%)

ECHO -
ECHO begin curl %DATE% %TIME%
ECHO curl -o %VS_INSTALLER_EXE% -L https://aka.ms/vs/%VS_MAJOR_VERSION%/release/%VS_INSTALLER_EXE%
curl -o %VS_INSTALLER_EXE% -L https://aka.ms/vs/%VS_MAJOR_VERSION%/release/%VS_INSTALLER_EXE%
IF ERRORLEVEL 1 exit /B %ERRORLEVEL%
ECHO end curl %DATE% %TIME%


ECHO -
ECHO begin install %DATE% %TIME%

ECHO %VS_INSTALLER_EXE% modify -q --wait %ADD_COMPONENTS% --InstallPath "%VS_INSTALLED_PATH%"
%VS_INSTALLER_EXE% modify -q --wait %ADD_COMPONENTS% --InstallPath "%VS_INSTALLED_PATH%"
SET RESULT=%ERRORLEVEL%
ECHO ERRORLEVEL=%RESULT%

ECHO end install %DATE% %TIME%

exit /B %RESULT%

Visual Studioの他のコンポーネントをインストールするには?

今回、Visual Studio 2022でVisual Studio 2015のプロジェクトをビルドすることが目的でした。そのため、Visual Studio 2022に、Visual Stduio 2015のビルドツールコンポーネント(Microsoft.VisualStudio.Component.VC.140)を追加するスクリプトを作成しました。

開発の現場では、同様に、別のVisual Studioのコンポーネントを自動追加したいことがあるかもしれません。その場合にも今回のスクリプトが利用できます。追加したいコンポーネントはスクリプトの冒頭で

SET ADD_COMPONENTS=--add Microsoft.VisualStudio.Component.VC.140

のように設定します。もし、複数のコンポーネントを追加したい場合は、

SET ADD_COMPONENTS=–add componentId1 –add componentId2

のように、--add の後ろにコンポーネントIdを追加していきます。

なお、Visual StudioのコンポーネントIdは、マイクロソフトの以下のサイトで確認できます。

Visual Studio のワークロードとコンポーネント ID

今回の投稿では、スクリプトを更新しました。前回の投稿で紹介したVisual Studioのコンポーネントを追加インストールするスクリプトは、Visual Studio 2022 Enterprise の特定のバージョンのみに適用できるスクリプトでした。今回の投稿では、そのスクリプトを汎用化し、Visual Studioの複数のバージョンや複数のエディションに対応し、また、追加するコンポーネントも変更できるようにしました。

スクリプトを更新した後は、Visual Studioのバージョンの更新があっても、同じスクリプトで問題なく動作しています。

コメントを残す