内藤 裕二/ 2019年 1月 25日/ 技術

TL;DR

  • 複数のバージョンのVisual Studioをインストールしている環境下において、使用したいバージョンのコマンドラインビルドに使用するMSBuild.exeを探すスクリプトを作成した

(2019.03.10追記)  
下記バージョンのMSBuild.exeのパスを追加  

  • Visual Studio 2013
  • Visual Studio 2017 Professional

参照URL

概要

かなりニッチな状況ですが、

  • Visual Studioで作成したツール類をコマンドラインからビルドしたい
  • Visual Studioのバージョンは特に指定しないけど、特定バージョン以降じゃないとビルドが通らない
  • ビルドする環境が32bit/64bit混在
    という状況になった際に、Power Shellスクリプトで解決したので、まとめておきます。

解説

スクリプト

スクリプトは、下記よりダウンロードできます。

https://github.com/rot-z/MSBuildSearch

スクリプト起動用のバッチ

Power Shellはデフォルト設定だと実行が禁止されていますので、権限指定してバッチファイルから指定します。

@echo off

cd /d %~dp0

powershell -NoProfile -ExecutionPolicy Unrestricted .\MSBuilsSearch_impl.ps1

pause

MSBuils.exeを探すPower Shellスクリプト

単純に、あらかじめリストで持っておいた"Program Files"フォルダ配下のパスにMSBuild.exeを探しています。
"Program Files"フォルダはOSのアーキテクチャによって"Program Files"(32bit), "Program Files (x86)"(64bit)と名前が異なりますので、そのあたりは勝手に解決しています。

# =============================================================================
#     search MSBuild.exe 
# =============================================================================

# folder paths of Visual Studio
$MSBUILD_12_PATH = "MSBuild`\12.0`\Bin"                                                             # Visual Studio 2013
$MSBUILD_14_PATH = "MSBuild`\14.0`\Bin"                                                             # Visual Studio 2015
$MSBUILD_15_COMMUNITY_PATH = "Microsoft Visual Studio`\2017`\Community`\MSBuild`\15.0`\Bin"         # Visual Studio 2017 Community
$MSBUILD_15_PROFESSIONAL_PATH = "Microsoft Visual Studio`\2017`\Professional`\MSBuild`\15.0`\Bin"   # Visual Studio 2017 Professional

# target paths for MSBuild
# sort by priority
[array]$SEARCH_PATHS = @(
        $MSBUILD_14_PATH, 
        $MSBUILD_15_COMMUNITY_PATH,
        $MSBUILD_15_PROFESSIONAL_PATH,
        $MSBUILD_12_PATH
    )

# get full path of "Program Files" folder from OS archtechture
$arch = (Get-WmiObject win32_operatingsystem | Select-Object osarchitecture)
$archName = $arch.osarchitecture
$programFilesDir = ""
if ($archName.StartsWith("64"))
{
    $programFilesDir = ${env:ProgramFiles(x86)}
}
else
{
    $programFilesDir = ${env:ProgramFiles}
}

# search MSBuild.exe
$msbuildPath = ""
foreach($p in $SEARCH_PATHS)
{
    # is folder exists?
    $targetPath = Join-Path $programFilesDir $p
    if (!(Test-Path $targetPath)) 
    {
        continue
    }

    # select the most shortest (shallowest) path
    $results = (Get-ChildItem $targetPath -Include MSBuild.exe -Recurse).FullName | Sort-Object -Property Length
    if ($results.Length -gt 0)
    {
        $msbuildPath = $results[0]
        Write-host $msbuildPath
    }
}

無償版のパスしか埋めてないのは、手元の環境で調査したからです。
適宜自分の環境に合わせてパスの追加を行ってください。