Skip to main content

Auto-discovering MSBuild.exe path build script.

:: ==================================
:: Option 1 (VS 2019 only)
:: from: https://github.com/morelinq/MoreLINQ/blob/master/msbuild.cmd
:: ==================================

@echo off
setlocal
if "%PROCESSOR_ARCHITECTURE%"=="x86" set PROGRAMS=%ProgramFiles%
if defined ProgramFiles(x86) set PROGRAMS=%ProgramFiles(x86)%
for %%e in (Community Professional Enterprise) do (
    if exist "%PROGRAMS%\Microsoft Visual Studio\2019\%%e\MSBuild\Current\Bin\MSBuild.exe" (
        set "MSBUILD=%PROGRAMS%\Microsoft Visual Studio\2019\%%e\MSBuild\Current\Bin\MSBuild.exe"
    )
)
if exist "%MSBUILD%" goto :build
set MSBUILD=
for %%i in (MSBuild.exe) do set MSBUILD=%%~dpnx$PATH:i
if not defined MSBUILD goto :nomsbuild
set MSBUILD_VERSION_MAJOR=
set MSBUILD_VERSION_MINOR=
for /f "delims=. tokens=1,2,3,4" %%m in ('msbuild /version /nologo') do (
    set MSBUILD_VERSION_MAJOR=%%m
)
if not defined MSBUILD_VERSION_MAJOR goto :nomsbuild
if %MSBUILD_VERSION_MAJOR% lss 16    goto :nomsbuild
:build
"%MSBUILD%" %*
goto :EOF

:nomsbuild
echo>&2 Microsoft Build Engine 16.0 or a later version is required to build
echo>&2 the solution. For installation instructions, see:
echo>&2 https://docs.microsoft.com/en-us/visualstudio/install/use-command-line-parameters-to-install-visual-studio
echo>&2 At the very least, you will want to install the MSBuilt Tool workload
echo>&2 that has the identifier "Microsoft.VisualStudio.Workload.MSBuildTools":
echo>&2 https://docs.microsoft.com/en-us/visualstudio/install/workload-component-id-vs-build-tools#msbuild-tools
exit /b s

:: ==================================
:: Option 2 (VS 2017 only)
:: from: https://github.com/morelinq/MoreLINQ/blob/master/msbuild.cmd
:: ==================================

rem ---------------------
rem MSBuild.exe Locations
rem ---------------------
rem
rem - Visual Studio 2017 Community Edition: `%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\MSBuild.exe`
rem - Visual Studio 2017 Professional Edition: `%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\Bin\MSBuild.exe`
rem - Visual Studio 2017 Enterprise Edition: `%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\MSBuild.exe`
rem - Visual Studio 2015: `%ProgramFiles(x86)%\MSBuild\14.0\Bin\MSBuild.exe`
rem - Visual Studio 2013: `%ProgramFiles(x86)%\MSBuild\12.0\Bin\MSBuild.exe`
rem - Visual Studio 2012 (and earlier): `%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe`
rem
rem NOTE: MSBuild.exe was included with Visual Studio since the release of Visual Studio 2013.
rem https://blogs.msdn.microsoft.com/visualstudio/2013/07/24/msbuild-is-now-part-of-visual-studio/
rem

@echo off
setlocal

::
:: msbuild.cmd - attempts to discover locally installed version of
:: VS 2017 15.1 (Community, Professional, Enterprise).
::
:: If discovered, all args passed to this script or forwarded to the
:: discovered msbuild.exe path.
::
:: Installation/Usage:
::
:: 1. Drop this script in a folder called <project>/tools/msbuild
:: 2. From your build script, make a "relative" path call to this script,
::    e.g.: `set MSBUILDCMD=%~dp0..\..\tools\msbuild\msbuild.cmd`
:: 3. Anywhere in your build script where you would `call msbuild[.exe] <args>`,
::    `call %MSBUILDCMD% <args>` instead.
::
:: Original source from Atif Aziz MoreLinq project @ <https://github.com/morelinq>
:: https://github.com/morelinq/MoreLINQ/blob/master/msbuild.cmd
::

if "%PROCESSOR_ARCHITECTURE%"=="x86" set PROGRAMS=%ProgramFiles%
if defined ProgramFiles(x86) set PROGRAMS=%ProgramFiles(x86)%
for %%e in (Community Professional Enterprise) do (
    if exist "%PROGRAMS%\Microsoft Visual Studio\2017\%%e\MSBuild\15.0\Bin\MSBuild.exe" (
        set "MSBUILD=%PROGRAMS%\Microsoft Visual Studio\2017\%%e\MSBuild\15.0\Bin\MSBuild.exe"
    )
)
if exist "%MSBUILD%" goto :build

set MSBUILD=
for %%i in (MSBuild.exe) do set MSBUILD=%%~dpnx$PATH:i
if not defined MSBUILD goto :nomsbuild
set MSBUILD_VERSION_MAJOR=
set MSBUILD_VERSION_MINOR=
for /f "delims=. tokens=1,2,3,4" %%m in ('msbuild /version /nologo') do (
    set MSBUILD_VERSION_MAJOR=%%m
    set MSBUILD_VERSION_MINOR=%%n
)
if not defined MSBUILD_VERSION_MAJOR goto :nomsbuild
if not defined MSBUILD_VERSION_MINOR goto :nomsbuild
if %MSBUILD_VERSION_MAJOR% lss 15    goto :nomsbuild
if %MSBUILD_VERSION_MINOR% lss 1     goto :nomsbuild

:build
"%MSBUILD%" %*
goto :EOF

:nomsbuild
echo>&2 Microsoft Build Engine 15.1 is required to build the solution. For
echo>&2 installation instructions, see:
echo>&2 https://docs.microsoft.com/en-us/visualstudio/install/use-command-line-parameters-to-install-visual-studio
echo>&2 At the very least, you will want to install the MSBuilt Tool workload
echo>&2 that has the identifier "Microsoft.VisualStudio.Workload.MSBuildTools":
echo>&2 https://docs.microsoft.com/en-us/visualstudio/install/workload-component-id-vs-build-tools#msbuild-tools
exit /b s

:: ==================================
:: Option 3 (more robust checking)
:: from: https://github.com/Microsoft/console/blob/master/tools/ColorTool/build.bat
:: ==================================

@echo off

rem Add path to MSBuild Binaries
set MSBUILD=()
for /f "usebackq tokens=*" %%f in (`where.exe msbuild.exe 2^>nul`) do (
    set MSBUILD="%%~ff"
    goto :FOUND_MSBUILD
)
if exist "%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\msbuild.exe" (
    set MSBUILD="%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\msbuild.exe"
    goto :FOUND_MSBUILD
)
if exist "%ProgramFiles%\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\msbuild.exe" (
    set MSBUILD="%ProgramFiles%\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\msbuild.exe"
    goto :FOUND_MSBUILD
)
if exist "%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\Bin\msbuild.exe" (
    set MSBUILD="%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\Bin\msbuild.exe"
    goto :FOUND_MSBUILD
)
if exist "%ProgramFiles%\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\Bin\msbuild.exe" (
    set MSBUILD="%ProgramFiles%\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\Bin\msbuild.exe"
    goto :FOUND_MSBUILD
)
if exist "%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\msbuild.exe" (
    set MSBUILD="%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\msbuild.exe"
    goto :FOUND_MSBUILD
)
if exist "%ProgramFiles%\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\msbuild.exe" (
    set MSBUILD="%ProgramFiles%\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\msbuild.exe"
    goto :FOUND_MSBUILD
)
if exist "%ProgramFiles(x86)%\Microsoft Visual Studio\2017\BuildTools\MSBuild\15.0\Bin\MSBuild.exe" (
    set MSBUILD="%ProgramFiles(x86)%\Microsoft Visual Studio\2017\BuildTools\MSBuild\15.0\Bin\MSBuild.exe"
    goto :FOUND_MSBUILD
)
if exist "%ProgramFiles(x86)%\MSBuild\14.0\bin" (
    set MSBUILD="%ProgramFiles(x86)%\MSBuild\14.0\bin\msbuild.exe"
    goto :FOUND_MSBUILD
)
if exist "%ProgramFiles%\MSBuild\14.0\bin" (
    set MSBUILD="%ProgramFiles%\MSBuild\14.0\bin\msbuild.exe"
    goto :FOUND_MSBUILD
)

if %MSBUILD%==() (
    echo "I couldn't find MSBuild on your PC. Make sure it's installed somewhere, and if it's not in the above if statements (in build.bat), add it."
    goto :EXIT
)
:FOUND_MSBUILD
set _MSBUILD_TARGET=Build
set _MSBUILD_CONFIG=Debug

:ARGS_LOOP
if (%1) == () goto :POST_ARGS_LOOP
if (%1) == (clean) (
    set _MSBUILD_TARGET=Clean,Build
)
if (%1) == (rel) (
    set _MSBUILD_CONFIG=Release
)
shift
goto :ARGS_LOOP

:POST_ARGS_LOOP
%MSBUILD% %~dp0ColorTool.sln /t:%_MSBUILD_TARGET% /m /nr:true /p:Configuration=%_MSBUILD_CONFIG%

if (%ERRORLEVEL%) == (0) (
    echo.
    echo Created exe in:
    echo    %~dp0ColorTool\bin\%_MSBUILD_CONFIG%\colortool.exe
    echo.
    echo Copying exe to root of project...
    copy %~dp0ColorTool\bin\%_MSBUILD_CONFIG%\colortool.exe %~dp0colortool.exe
    echo Done.
    echo.
)

:EXIT