如何在批处理文件中找到最新的 Visual Studio 开发人员命令提示符?

How can I find the latest Visual Studio Developer Command Prompt in a batch file?

我需要编写一个批处理文件来完成 Visual Studio 中的预构建步骤。作为其中的一部分,我需要调用 Visual Studio 开发人员命令提示符。

我知道对于 VS2015,开发人员命令提示符位于 C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools\VsDevCmd.bat

不幸的是,我们的构建服务器有不同版本的 VS。有没有一种简单的方法可以在批处理文件中找到 Visual Studio 的所有(或大多数)版本的最新 VSDevCmd.bat,以便预构建步骤适用于两种环境?

我设法拼凑了一个查看参数的批处理文件,然后查看文件系统以尝试找出应该使用哪个版本的 VSDevCmd。 $(DevEnvDir) 有时是 *Undefined*,所以我们也需要检查一下。

已在 VS2015 Professional、VS2017 Professional 和 VS2017 Enterprise 上测试。

REM Usage in VS build event: call "$(SolutionDir)\find_vsdevcmd.bat" "$(DevEnvDir)"

SET vsversion=

REM Get Visual Studio version, either from command prompt, or newest on filesystem 
if [%1] == [] (
  if exist "C:\Program Files (x86)\Microsoft Visual Studio17\Enterprise\Common7\Tools\VsDevCmd.bat" (
    SET vsversion="VS2017 Enterprise"
  ) else if exist "C:\Program Files (x86)\Microsoft Visual Studio17\Professional\Common7\Tools\VsDevCmd.bat" (
    SET vsversion="VS2017 Professional"
  ) else if exist "C:\Program Files (x86)\Microsoft Visual Studio17\Community\Common7\Tools\VsDevCmd.bat" (
    SET vsversion="VS2017 Community"
  ) else if exist "C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools\VsDevCmd.bat" (
    SET vsversion="VS2015"
  ) else if exist "C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\Tools\VsDevCmd.bat" (
    SET vsversion="VS2013"
  ) else goto :eof
) else if [%1] == ["*Undefined*"] (
  if exist "C:\Program Files (x86)\Microsoft Visual Studio17\Enterprise\Common7\Tools\VsDevCmd.bat" (
    SET vsversion="VS2017 Enterprise"
  ) else if exist "C:\Program Files (x86)\Microsoft Visual Studio17\Professional\Common7\Tools\VsDevCmd.bat" (
    SET vsversion="VS2017 Professional"
  ) else if exist "C:\Program Files (x86)\Microsoft Visual Studio17\Community\Common7\Tools\VsDevCmd.bat" (
    SET vsversion="VS2017 Community"
  ) else if exist "C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools\VsDevCmd.bat" (
    SET vsversion="VS2015"
  ) else if exist "C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\Tools\VsDevCmd.bat" (
    SET vsversion="VS2013"
  ) else goto :eof
) else (
  if [%1] == ["C:\Program Files (x86)\Microsoft Visual Studio17\Enterprise\Common7\IDE\"] (
    SET vsversion="VS2017 Enterprise"
  ) else if [%1] == ["C:\Program Files (x86)\Microsoft Visual Studio17\Professional\Common7\IDE\"] (
    SET vsversion="VS2017 Professional"
  ) else if [%1] == ["C:\Program Files (x86)\Microsoft Visual Studio17\Community\Common7\IDE\"] (
    SET vsversion="VS2017 Community"
  ) else if [%1] == ["C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\" (
    SET vsversion="VS2015"
  ) else if [%1] == ["C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\" (
    SET vsversion="VS2013"
  ) else goto :eof
)

if %vsversion% == "VS2017 Enterprise" (
    SET vsdevcmd="C:\Program Files (x86)\Microsoft Visual Studio17\Enterprise\Common7\Tools\VsDevCmd.bat"
    ECHO VS2017 Enterprise
) else if %vsversion% == "VS2017 Professional" (
    SET vsdevcmd="C:\Program Files (x86)\Microsoft Visual Studio17\Professional\Common7\Tools\VsDevCmd.bat"
    ECHO VS2017 Professional
) else if %vsversion% == "VS2017 Community" (
    SET vsdevcmd="C:\Program Files (x86)\Microsoft Visual Studio17\Community\Common7\Tools\VsDevCmd.bat"
    ECHO VS2017 Community
) else if %vsversion% == "VS2015" (
    SET vsdevcmd="C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools\VsDevCmd.bat"
    ECHO VS2015
) else if %vsversion% == "VS2013" (
    SET vsdevcmd="C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\Tools\VsDevCmd.bat"
    ECHO VS2013
) else goto :eof

call %vsdevcmd%

我为 CI-CD 机器所做的事情是对非 2017 机器使用 vcvarsall,对 2017 机器使用 vsdevcmd。下面的脚本片段:

rem vsvarsall.bat does not work if there are quoted paths on %PATH%
set path=%path:"=%
rem this will work for non VS 2017 build machines
if exist "c:\progra~2\Micros~1.0\vc\vcvarsall.bat" (
    call c:\progra~2\Micros~1.0\vc\vcvarsall.bat && goto :SetVSEnvFinished
)

echo vcvarsall.bat not found, looking for vsdevcmd.bat
rem Find and run vsdevcmd.bat
set "VS_PATH=C:\Program Files (x86)\Microsoft Visual Studio17"

rem The 2017 folder will not be present in Visual Studio 2017 Preview machines (such as 15.8 preview)
if not exist "%VS_PATH%" (
    set "VS_PATH=C:\Program Files (x86)\Microsoft Visual Studio"
)

if not exist "%VS_PATH%" (
    echo "%VS_PATH%" not found. Is Visual Studio installed? && goto :ErrorExit
)

for /f "delims=" %%F in ('dir /b /s "%VS_PATH%\vsdevcmd.bat" 2^>nul') do set VSDEVCMD_PATH=%%F
echo ********Executing %VSDEVCMD_PATH%********
call "%VSDEVCMD_PATH%"
goto :SetVSEnvFinished

:ErrorExit
exit /b 1

:SetVSEnvFinished

所以对于非2017的,它会执行vcvarsall.bat(设置VS环境)。对于 2017 版本,它将搜索 vsdevcmd.bat(在特定文件夹中以减少搜索时间)和 运行。 希望这有帮助。

你应该使用 vswhere provided by the Microsoft Visual Studio Installer. You copy vswhere.exe to a known location. The wiki has a description on how to start the developer command prompt:

@if not defined _echo echo off
for /f "usebackq delims=" %%i in (`vswhere.exe -prerelease -latest -property installationPath`) do (
  if exist "%%i\Common7\Tools\vsdevcmd.bat" (
    %comspec% /k "%%i\Common7\Tools\vsdevcmd.bat" %*
    exit /b
  )
)

rem Instance or command prompt not found
exit /b 2