Check Visual Studio Shell Installation from Batch - windows

How can we check if and which version of Visual Studio Shell is installed, from a batch script?
I understand we can check the existence of file/folder say under
C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE
But I am looking for a more elegant and generic solution.
Any help?
Update to accepted answer:
Your answer is elegant and does the task. Since I was specifically checking for certain versions, I am using (after checking the link you provided):
#echo off
reg query "HKEY_CLASSES_ROOT\VisualStudio.DTE.10.0" >> nul 2>&1
if %ERRORLEVEL% NEQ 0 ( echo VS 2010 not installed ) else ( echo VS 2010 installed. )
reg query "HKEY_CLASSES_ROOT\VisualStudio.DTE.11.0" >> nul 2>&1
if %ERRORLEVEL% NEQ 0 ( echo VS 2012 not installed ) else ( echo VS 2012 installed. )

#echo off
for /d %%a in ("%programfiles%\Microsoft Visual Studio*") do (
for /f "tokens=3 delims=\" %%x in ("%%a") do echo %%x
)
pause >nul
If you need more details there are plenty of reg keys you can query to get more info but that would be much harder to extract the data you wanted from the keys and values.
Note: If you are running on x64 then you may need to add a check for %systemdrive%\Program Files (x86) depending on where VS is installed.

Related

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

I need to write a batch file to complete a pre-build step in Visual Studio. As part of it, I need to call the Visual Studio Developer Command Prompt.
I know that for VS2015, the developer command prompt is located in C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools\VsDevCmd.bat.
Unfortunately, our build server has a different version of VS. Is there a simple way to find the latest VSDevCmd.bat for all (or most) versions of Visual Studio in a batch file, so the pre-build step will work on both environments?
You should use 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
The thing that I do for CI-CD machines is use vcvarsall for non 2017 machines and vsdevcmd for 2017 ones. Script snippet below:
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 Studio\2017"
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
So for non 2017 ones, it will execute vcvarsall.bat (which sets up the VS environment). For 2017 versions, it will search for vsdevcmd.bat (in specific folder to reduce search time) and run it.
Hope this helps.
I've managed to cobble together a batch file that looks at parameters, then at the filesystem to try to figure out what version of VSDevCmd should be used. $(DevEnvDir) is sometimes *Undefined*, so we need to check for that too.
Tested on VS2015 Professional, VS2017 Professional, and 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 Studio\2017\Enterprise\Common7\Tools\VsDevCmd.bat" (
SET vsversion="VS2017 Enterprise"
) else if exist "C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\Tools\VsDevCmd.bat" (
SET vsversion="VS2017 Professional"
) else if exist "C:\Program Files (x86)\Microsoft Visual Studio\2017\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 Studio\2017\Enterprise\Common7\Tools\VsDevCmd.bat" (
SET vsversion="VS2017 Enterprise"
) else if exist "C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\Tools\VsDevCmd.bat" (
SET vsversion="VS2017 Professional"
) else if exist "C:\Program Files (x86)\Microsoft Visual Studio\2017\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 Studio\2017\Enterprise\Common7\IDE\"] (
SET vsversion="VS2017 Enterprise"
) else if [%1] == ["C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\IDE\"] (
SET vsversion="VS2017 Professional"
) else if [%1] == ["C:\Program Files (x86)\Microsoft Visual Studio\2017\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 Studio\2017\Enterprise\Common7\Tools\VsDevCmd.bat"
ECHO VS2017 Enterprise
) else if %vsversion% == "VS2017 Professional" (
SET vsdevcmd="C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\Tools\VsDevCmd.bat"
ECHO VS2017 Professional
) else if %vsversion% == "VS2017 Community" (
SET vsdevcmd="C:\Program Files (x86)\Microsoft Visual Studio\2017\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%

Programmatically finding the VS2017 installation directory

With previous versions of VS you could query the registry to determine the installation directory for VS:
HKLM\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\14.0
However, this doesn't seem to work with the VS2017 RC. We have scripts that detect the latest installed VS and then do "the right thing", and so far I'm having issues plugging VS2017 into those systems.
Does anyone know how to programmatically determine the installation location for VS2017?
You can use vswhere tool to get VS2017 location.
Example:
#echo off
rem VS2017U2 contains vswhere.exe
if "%VSWHERE%"=="" set "VSWHERE=%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe"
for /f "usebackq tokens=*" %%i in (`"%VSWHERE%" -latest -products * -requires Microsoft.Component.MSBuild -property installationPath`) do (
set InstallDir=%%i
)
if exist "%InstallDir%\MSBuild\15.0\Bin\MSBuild.exe" (
"%InstallDir%\MSBuild\15.0\Bin\MSBuild.exe" %*
)
You can read more about it here: https://blogs.msdn.microsoft.com/heaths/2017/02/25/vswhere-available/
Visual Studio 2017 supports no-registry, side-by-side installations of all SKUs (Enterprise, Professional and Community).
MSI installlers can query via APIs described here:
https://blogs.msdn.microsoft.com/heaths/2016/09/15/changes-to-visual-studio-15-setup/
Examples are here:
https://code.msdn.microsoft.com/Visual-Studio-Setup-0cedd331
https://github.com/microsoft/vs-setup-samples
KindDragon's solution didn't quite work for me due to batch's "delayed expansion" "feature". (WAT)
Here is my code, compatible with VS 2017 15.2 (for the vswhere.exe installation)
SETLOCAL EnableDelayedExpansion
if not exist "%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" (
echo "WARNING: You need VS 2017 version 15.2 or later (for vswhere.exe)"
)
for /f "usebackq tokens=*" %%i in (`"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -latest -products * -requires Microsoft.Component.MSBuild -property installationPath`) do (
set InstallDir=%%i
)
if exist "!InstallDir!\VC\Auxiliary\Build\vcvars64.bat" (
call "!InstallDir!\VC\Auxiliary\Build\vcvars64.bat"
) else (
echo "Could not find !InstallDir!\VC\Auxiliary\Build\vcvars64.bat"
)
Especially note usage of SETLOCAL EnableDelayedExpansion and !InstallDir!
Well, vswhere.exe doesn't really supply more than the Visual Studio edition installation path. Here's my .profile file Interix snippet from 2008 doing the same with a minor update (shell script):
if [[ -n $PROCESSOR_ARCHITEW6432 || $PROCESSOR_ARCHITECTURE != "x86" ]]; then
hkeybase='HKLM\SOFTWARE\Wow6432Node\Microsoft\'
else
hkeybase='HKLM\SOFTWARE\Microsoft\'
fi
for vsver in "15.0" "14.0" "12.0" "11.0" "10.0" "9.0" "8.0"; do
_vsinstalldir=$(reg.exe query ${hkeybase}'VisualStudio\SxS\VS7' -v $vsver 2>/dev/null \
| sed -n 's|.*REG_SZ *\([ [:print:]]*\).*|\1|p' | sed 's|\\|/|g')
if [[ -n $_vsinstalldir ]]; then break; fi
done; unset vsver
That's enumerating Visual Studio installations favouring the latest in registry key
HKLM\SOFTWARE\Microsoft\VisualStudio\SxS\VS7
Still working for Visual Studio 2017. Would be easy to translate to cmd syntax. To query the registry is simpler and doesn't require vswhere.exe in your path, thus favourable IMO.
Now finding the current Visual C++ instance and the SDKs is another task entirely. :D
Common output in case you wonder:
C:/Program Files (x86)/Microsoft Visual Studio/2017/Enterprise/
I had a devil of time trying to modify Srekel's answer to search for only VS2017. Note: If you put the "for" statement below inside an "if" block it will wreck the escape characters and won't work.
SETLOCAL EnableDelayedExpansion
if not exist "%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" (
echo "WARNING: You need VS 2017 version 15.2 or later (for vswhere.exe)"
)
set vswherestr=^"!ProgramFiles(x86)!\Microsoft Visual Studio\Installer\vswhere.exe^" -version [15.0,16.0^^) -products * -requires Microsoft.Component.MSBuild -property installationPath
for /f "usebackq tokens=*" %%i in (`!vswherestr!`) do (
set BUILDVCTOOLS=%%i\Common7\Tools
echo BUILDVCTOOLS: !BUILDVCTOOLS!
if not exist !BUILDVCTOOLS!\VsDevCmd.bat (
echo Error: Cannot find VS2017 Build Tools
goto :buildfailed
)
call "!BUILDVCTOOLS!\VsDevCmd.bat"
)
May I recommend my package get-vs2017-path it uses only built-in Windows tools (and although it's built as an NPM package, it has no dependencies, and the tools folder works standalone)
See following answer in here:
https://stackoverflow.com/a/55754831/2338477
You can use either command line tool for querying Visual studio location, but I also provide programmatic way to query Visual Studio location. Code is based upon vswhere source code, but simplified.
We have only 3 Visual Studio editions.
\Community
\Professional
\Enterprise
As such we can simplify everything a bit.
Here some tested CMD script.
#SET env_all_vs2017_root=%ProgramFiles(x86)%\Microsoft Visual Studio\2017
#SET env_vs2017_path="%env_all_vs2017_root%\Professional"
#IF NOT EXIST %env_vs2017_path% SET env_vs2017_path="%env_all_vs2017_root%\Community"
#IF NOT EXIST %env_vs2017_path% SET env_vs2017_path="%env_all_vs2017_root%\Enterprise"
#REM Let's fail laudly
#IF NOT EXIST %env_vs2017_path% SET "env_vs2017_path=Visual Studio 2017 install path was not found by %~nx0"
#REM You may want to remove quotes
#SET unquoted=%env_vs2017_path:"=%
#REM And now let's see the result and PAUSE
#ECHO VS 2017 install path is
#ECHO %unquoted%
#PAUSE
You can use this PowerShell snippet for finding the VS2017 installation directory:
$vssetup_path = "$([Environment]::GetFolderPath("MyDocuments"))\WindowsPowerShell\Modules\VSSetup"
if (-not (Test-Path $vssetup_path -pathType container))
{
iwr https://github.com/Microsoft/vssetup.powershell/releases/download/1.0.36-rc/VSSetup.zip -OutFile "$env:TEMP\VSSetup.zip"
Expand-Archive "$env:TEMP\VSSetup.zip" $vssetup_path
}
$vs2017 = Get-VSSetupInstance -All | Select-VSSetupInstance -Require 'Microsoft.VisualStudio.Workload.NativeDesktop' -Version '[15.0,16.0)' -Latest
"Installation Path: " + $vs2017.InstallationPath
#`vsdevcmd.bat -arch=x86` or `vsdevcmd.bat -arch=amd64` can be used to setup path's to VC++ compiler
"VsDevCmd.bat Path: " + $vs2017.InstallationPath + "\Common7\Tools\VsDevCmd.bat"
I use powershell like KindDragon suggested
$Is64bitOs = $env:PROCESSOR_ARCHITEW6432 -eq 'AMD64';
if ($Is64bitOs){
$registryPath = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\VisualStudio\14.0";
}
else {
$registryPath = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\14.0";
}
$VSInstallDir = (Get-ItemProperty -Path Registry::HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\VisualStudio\14.0 -Name ShellFolder).ShellFolder;

Recursively search for, and build, arbitrary VS solutions using a batch script w/ command line args

So, I want to be able to build an arbitrary number of VS solutions using a batch script. I would want the script to search for the given project names, and pass their filepaths to the VS CLI.The format would be along the lines of:
build_slns (debug|release) [proj1] [proj2] ... [projN]
The first arg would be the configuration, and all subsequent args would be project names. The part I'm having trouble with, is that these projects will all be in different subdirectories of my base code directory. So an example would be something like this:
build_slns debug foo bar foobar
And the .slns I want to build would be located like so:
Code\foo\foo.sln
Code\foo\bar\bar.sln
Code\foobar\foobar.sln
I believe I'll want to use FOR /F, but I'm just not familiar enough with batch to get it working the way I want it to. Any guidance here is greatly appreciated.
Something like this should work
#echo off
setlocal
::change the definition of cmd and root as needed
set cmd="C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\devenv.exe"
set root="d:\utils"
:loop
if "%~2" equ "" exit /b
echo Searching for %2
for /f "eol=: delims=" %%F in ('dir /b /s "%root%\%2.sln"') do (
echo Building %%F
%cmd% "%%F" /build %1
)
shift /2
goto :loop

Compiling boost library for Windows Embedded Compact 7

I'm programming for an embedded device with a NVIDIA Tegra 2 running Windows Embedded Compact 7. My development environment is Microsoft Visual Studio 2008. The boost library and especially the boost-asio package seems to be very helpfull for my needs. Unfortunately I was not able to find a good guide on how to get boost running on Windows Embedded Compact 7. I'd prefere to get .lib files which I can link statically into my application.
It appears that the documentation on this process is sparse, because it requires non-trivial updates to the build process to get working with Windows CE. The most comprehensive tutorial to this problem appears to be here.
Since you explicitly tagged this boost-asio, I also looked into that component of Boost specifically. Here's a thread from the Boost mailing list that covers this library in detail, including potential failure cases you may experience, JAM file modifications, and a batch file to help you with the build.*
For those reading this: please share your experiences once you get this working. Despite various concerns that Boost is too memory-heavy for embedded applications, Boost provides the ability to use separate packages to meet your needs. I expect other users on SO will be very interested in your experiences getting this working.
* Because people have been expressing problems with the referenced batch file disappearing when Nabble links expire, here's a pastedump for posterity:
#SET VCINSTALLDIR=%VS9INSTALLDIR%\VC
#if "%VS9INSTALLDIR%"=="" goto error_no_VSINSTALLDIR
#if "%VCINSTALLDIR%"=="" goto error_no_VCINSTALLDIR
#echo Setting environment for using Microsoft Visual Studio 2008 tools for WM5.
#set TARGETCPU=X86
#call :GetWindowsSdkDir
#if not "%WindowsSdkDir%" == "" (
set "PATH=%WindowsSdkDir%bin;%PATH%"
)
#rem
#rem Root of Visual Studio IDE installed files.
#rem
#set DevEnvDir=%VS9INSTALLDIR%\Common7\IDE
#set PATH=%VCINSTALLDIR%\CE\bin\x86_arm;%VCINSTALLDIR%\bin;%VS9INSTALLDIR%\Common7\Tools;%DevEnvDir%;%VS9INSTALLDIR%\Common\Tools;%VS9INSTALLDIR%\Common\IDE;%VS9INSTALLDIR%;%PATH%
#set INCLUDE=%STLPORT_PATH%\STLPort-5.2.1\stlport;%VCINSTALLDIR%\ce\include;%CETOOLS%\Windows Mobile 5.0 Pocket PC SDK\include\ARMV4I;%CETOOLS%\Windows Mobile 5.0 Pocket PC SDK\include;%VCINSTALLDIR%\ce\atlmfc\include
#set LIB=%STLPORT_PATH%\STLPort-5.2.1\lib\evc9-arm;%CETOOLS%\Windows Mobile 5.0 Pocket PC SDK\lib\ARMV4I;%VCINSTALLDIR%\ce\ATLMFC\LIB\ARMV4I;%VCINSTALLDIR%\ce\LIB\ARMV4I
#set LIBPATH=
#goto end
:GetWindowsSdkDir
#call :GetWindowsSdkDirHelper HKLM > nul 2>&1
#if errorlevel 1 call :GetWindowsSdkDirHelper HKCU > nul 2>&1
#if errorlevel 1 set WindowsSdkDir=%VCINSTALLDIR%\PlatformSDK\
#exit /B 0
:GetWindowsSdkDirHelper
#for /F "tokens=1,2*" %%i in ('reg query "%1\SOFTWARE\Microsoft\Microsoft SDKs\Windows" /v "CurrentInstallFolder"') DO (
if "%%i"=="CurrentInstallFolder" (
SET "WindowsSdkDir=%%k"
)
)
#if "%WindowsSdkDir%"=="" exit /B 1
#exit /B 0
:error_no_VSINSTALLDIR
#echo ERROR: VS9INSTALLDIR variable is not set.
#goto end
:error_no_VCINSTALLDIR
#echo ERROR: VCINSTALLDIR variable is not set.
#goto end
:end
#SET VCINSTALLDIR=%VS9INSTALLDIR%\VC
#SET FrameworkDir=C:\WINDOWS\Microsoft.NET\Framework
#SET FrameworkVersion=v2.0.50727
#SET Framework35Version=v3.5
#if "%VS9INSTALLDIR%"=="" goto error_no_VSINSTALLDIR
#if "%VCINSTALLDIR%"=="" goto error_no_VCINSTALLDIR
#echo Setting environment for using Microsoft Visual Studio 2008 x86 tools with STLport-5.2.1.
#call :GetWindowsSdkDir
#if not "%WindowsSdkDir%" == "" (
set "PATH=%WindowsSdkDir%bin;%PATH%"
set "INCLUDE=%WindowsSdkDir%include;%INCLUDE%"
set "LIB=%WindowsSdkDir%lib;%LIB%"
)
#rem
#rem Root of Visual Studio IDE installed files.
#rem
#set DevEnvDir=%VS9INSTALLDIR%\Common7\IDE
#set PATH=%DevEnvDir%;%VCINSTALLDIR%\BIN;%VS9INSTALLDIR%\Common7\Tools;%FrameworkDir%\%Framework35Version%;%FrameworkDir%\%FrameworkVersion%;%VCINSTALLDIR%\VCPackages;%PATH%
#set INCLUDE=%STLPORT_PATH%\STLport-5.2.1\stlport;%VCINSTALLDIR%\ATLMFC\INCLUDE;%VCINSTALLDIR%\INCLUDE;%INCLUDE%
#set LIB=%STLPORT_PATH%\STLport-5.2.1\lib\vc9;%VCINSTALLDIR%\ATLMFC\LIB;%VCINSTALLDIR%\LIB;%LIB%
#set LIBPATH=%FrameworkDir%\%Framework35Version%;%FrameworkDir%\%FrameworkVersion%;%VCINSTALLDIR%\ATLMFC\LIB;%VCINSTALLDIR%\LIB;%LIBPATH%
#goto end
:GetWindowsSdkDir
#call :GetWindowsSdkDirHelper HKLM > nul 2>&1
#if errorlevel 1 call :GetWindowsSdkDirHelper HKCU > nul 2>&1
#if errorlevel 1 set WindowsSdkDir=%VCINSTALLDIR%\PlatformSDK\
#exit /B 0
:GetWindowsSdkDirHelper
#for /F "tokens=1,2*" %%i in ('reg query "%1\SOFTWARE\Microsoft\Microsoft SDKs\Windows" /v "CurrentInstallFolder"') DO (
if "%%i"=="CurrentInstallFolder" (
SET "WindowsSdkDir=%%k"
)
)
#if "%WindowsSdkDir%"=="" exit /B 1
#exit /B 0
:error_no_VSINSTALLDIR
#echo ERROR: VSINSTALLDIR variable is not set.
#goto end
:error_no_VCINSTALLDIR
#echo ERROR: VCINSTALLDIR variable is not set.
#goto end
:end

How to find Windows SDK's SetEnv.cmd / SetEnv.cmd Does not work correctly

We have a Team City Build Server running and want to compile a Visual C++ project. So far this would be easy, since I've setup our Windows Build Agent with the Windows SDK, but we don't have a solution / project file.
The project files are instead created with CMake. CMake seems to be a little bit dumb (can't generate Solution when Visual Studio is not installed), but with some tricks, I could get it to do it. The solution can then be built with MSBuild.
And here comes the problem. For this to work automatically, I need to call the Windows SDK's SetEnv.cmd. And I can't seem to find it automatically. It's in the bin sub directory of the Windows SDK, but neither bin nor the root are in the path, and the %mssdk% environment variable is set by the SetEnv.cmd and is not available beforehand!
Adding the Windows SDK\bin dir to the PATH leads to SetEnv.cmd no longer working (exits with a message like The x86 compilers are not currently installed and Jump target Set_x86 not found.
The start menu link is calling the SetEnv.cmd with the Windows SDK dir as working directory instead. But if I add the root directory to the PATH, Bin\SetEnv.cmd is not available.
How can I find SetEnv.cmd automatically? Even setting an environment variable to the full path of the setenv.cmd doesn't work, and when I define %mssdk% as the sdk dir, then call %mssdk%\bin\SetEnv doesn't work as well. I also tried to define %mssdk%, then cd %mssdk%, then calling bin\SetEnv. Also compilers not found in all these cases. It also doesn't work if I manually cd to the root or bin dir on a command line and then call SetEnv.cmd...
The start menu link works fine though.
For the record, my solution for now, as strange as this is, is the following:
I created a MSBuild file that creates the solution file with CMake on the command line, then invokes the created solution with a MSBuild task. The MSBuild file can be easily built from TeamCity, though I needed some additional tricks to satisfy CMake's stupid looking for the compiler, though I won't invoke it thing. Not really satisfying, but it works.
My solution (sets %WindowsSdkPath%, so that SetEnv.cmd could be found under %WindowsSdkPath%Bin\):
#ECHO OFF
IF "%WindowsSdkVersion%"=="" (
CALL :SetWindowsSdkVersionHelper HKCU > nul 2>&1
IF ERRORLEVEL 1 CALL :SetWindowsSdkVersionHelper HKLM > nul 2>&1
IF ERRORLEVEL 1 GOTO ERROR_NOWSDK
)
CALL :SetWindowsSdkPathHelper > nul 2>&1
IF ERRORLEVEL 1 GOTO ERROR_NOWSDK
GOTO END
:SetWindowsSdkPathHelper
SET WindowsSdkPath=
FOR /F "tokens=1,2*" %%i in ('REG QUERY "HKLM\SOFTWARE\Microsoft\Microsoft SDKs\Windows\%WindowsSdkVersion%" /V InstallationFolder') DO (
IF "%%i"=="InstallationFolder" (
SET "WindowsSdkPath=%%k"
)
)
IF "%WindowsSdkPath%"=="" EXIT /B 1
EXIT /B 0
:SetWindowsSdkVersion
CALL :GetWindowsSdkVersionHelper HKCU > nul 2>&1
IF ERRORLEVEL 1 CALL :GetWindowsSdkVersionHelper HKLM > nul 2>&1
IF ERRORLEVEL 1 EXIT /B 1
EXIT /B 0
:SetWindowsSdkVersionHelper
SET WindowsSdkVersion=
FOR /F "tokens=1,2*" %%i in ('REG QUERY "%1\SOFTWARE\Microsoft\Microsoft SDKs\Windows" /V "CurrentVersion"') DO (
IF "%%i"=="CurrentVersion" (
SET "WindowsSdkVersion=%%k"
)
)
IF "%WindowsSdkVersion%"=="" EXIT /B 1
EXIT /B 0
:ERROR_NOWSDK
ECHO The Windows SDK %WindowsSdkVersion% could not be found.
EXIT /B 1
:END
I was inspired for this by the SetEnv.cmd itself...
Mac, nice answer!
Now I would like to run msbuild with my project file. But before I should run SetEnv.Cmd - right?
So, here we go:
run_Macs_code.bat REM see above
call "%WindowsSdkPath%\bin\Setenv.cmd" /Release /x86 /xp
cd E:\client
msbuild client.proj
Now it's working :)

Resources