diff --git a/.gitignore b/.gitignore
index 9493fdad5..1bb24d891 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,6 +10,7 @@ test*.xml
test*_results.txt
test_failures.txt
build
+_build
packages
Debug
Release
diff --git a/build_test_all.cmd b/build_test_all.cmd
index c9beb852c..dddfb00f4 100644
--- a/build_test_all.cmd
+++ b/build_test_all.cmd
@@ -9,33 +9,41 @@ if "%target_platform%"=="" set target_platform=x64
if "%target_configuration%"=="" set target_configuration=Release
if "%target_version%"=="" set target_version=999.999.999.999
+call "%~dp0ensure_vsbuild.cmd" "%target_platform%"
+if errorlevel 1 exit /b %errorlevel%
+
if not exist ".\.nuget" mkdir ".\.nuget"
if not exist ".\.nuget\nuget.exe" powershell -Command "$ProgressPreference = 'SilentlyContinue' ; Invoke-WebRequest https://dist.nuget.org/win-x86-commandline/latest/nuget.exe -OutFile .\.nuget\nuget.exe"
-call .nuget\nuget.exe restore cppwinrt.sln"
+call .nuget\nuget.exe restore cppwinrt.sln
call .nuget\nuget.exe restore natvis\cppwinrtvisualizer.sln
call .nuget\nuget.exe restore test\nuget\NugetTest.sln
call msbuild /m /p:Configuration=%target_configuration%,Platform=%target_platform%,CppWinRTBuildVersion=%target_version% cppwinrt.sln /t:fast_fwd
+if errorlevel 1 exit /b %errorlevel%
call msbuild /p:Configuration=%target_configuration%,Platform=%target_platform%,Deployment=Component;CppWinRTBuildVersion=%target_version% natvis\cppwinrtvisualizer.sln
+if errorlevel 1 exit /b %errorlevel%
+
call msbuild /p:Configuration=%target_configuration%,Platform=%target_platform%,Deployment=Standalone;CppWinRTBuildVersion=%target_version% natvis\cppwinrtvisualizer.sln
+if errorlevel 1 exit /b %errorlevel%
if "%target_platform%"=="arm64" goto :eof
-call msbuild /m /p:Configuration=%target_configuration%,Platform=%target_platform%,CppWinRTBuildVersion=%target_version% cppwinrt.sln /t:cppwinrt
+set cppwinrt_targets=cppwinrt
+set cppwinrt_targets=%cppwinrt_targets%;test\test
+set cppwinrt_targets=%cppwinrt_targets%;test\test_nocoro
+set cppwinrt_targets=%cppwinrt_targets%;test\test_cpp20
+set cppwinrt_targets=%cppwinrt_targets%;test\test_cpp20_no_sourcelocation
+set cppwinrt_targets=%cppwinrt_targets%;test\test_fast
+set cppwinrt_targets=%cppwinrt_targets%;test\test_slow
+set cppwinrt_targets=%cppwinrt_targets%;test\test_module_lock_custom
+set cppwinrt_targets=%cppwinrt_targets%;test\test_module_lock_none
+set cppwinrt_targets=%cppwinrt_targets%;test\old_tests\test_old
+call msbuild /m /p:Configuration=%target_configuration%,Platform=%target_platform%,CppWinRTBuildVersion=%target_version% cppwinrt.sln "/t:%cppwinrt_targets%"
+if errorlevel 1 exit /b %errorlevel%
call msbuild /p:Configuration=%target_configuration%,Platform=%target_platform%,CppWinRTBuildVersion=%target_version% test\nuget\NugetTest.sln
-
-call msbuild /m /p:Configuration=%target_configuration%,Platform=%target_platform%,CppWinRTBuildVersion=%target_version% cppwinrt.sln /t:test\test
-call msbuild /m /p:Configuration=%target_configuration%,Platform=%target_platform%,CppWinRTBuildVersion=%target_version% cppwinrt.sln /t:test\test_nocoro
-call msbuild /m /p:Configuration=%target_configuration%,Platform=%target_platform%,CppWinRTBuildVersion=%target_version% cppwinrt.sln /t:test\test_cpp20
-call msbuild /m /p:Configuration=%target_configuration%,Platform=%target_platform%,CppWinRTBuildVersion=%target_version% cppwinrt.sln /t:test\test_cpp20_no_sourcelocation
-call msbuild /m /p:Configuration=%target_configuration%,Platform=%target_platform%,CppWinRTBuildVersion=%target_version% cppwinrt.sln /t:test\test_fast
-call msbuild /m /p:Configuration=%target_configuration%,Platform=%target_platform%,CppWinRTBuildVersion=%target_version% cppwinrt.sln /t:test\test_slow
-call msbuild /m /p:Configuration=%target_configuration%,Platform=%target_platform%,CppWinRTBuildVersion=%target_version% cppwinrt.sln /t:test\test_module_lock_custom
-call msbuild /m /p:Configuration=%target_configuration%,Platform=%target_platform%,CppWinRTBuildVersion=%target_version% cppwinrt.sln /t:test\test_module_lock_none
-call msbuild /m /p:Configuration=%target_configuration%,Platform=%target_platform%,CppWinRTBuildVersion=%target_version% cppwinrt.sln /t:test\test_module_lock_none
-call msbuild /m /p:Configuration=%target_configuration%,Platform=%target_platform%,CppWinRTBuildVersion=%target_version% cppwinrt.sln /t:test\old_tests\test_old
+if errorlevel 1 exit /b %errorlevel%
call run_tests.cmd %target_platform% %target_configuration%
diff --git a/cppwinrt/cppwinrt.vcxproj b/cppwinrt/cppwinrt.vcxproj
index b8beed890..d3f60f531 100644
--- a/cppwinrt/cppwinrt.vcxproj
+++ b/cppwinrt/cppwinrt.vcxproj
@@ -311,4 +311,9 @@
+
+
+ {A63B3AD1-AB7B-461E-9FFF-2447F5BCD459}
+
+
\ No newline at end of file
diff --git a/ensure_vsbuild.cmd b/ensure_vsbuild.cmd
new file mode 100644
index 000000000..5288eabf6
--- /dev/null
+++ b/ensure_vsbuild.cmd
@@ -0,0 +1,70 @@
+@echo off
+
+set "target_platform=%~1"
+if "%target_platform%"=="" set "target_platform=x64"
+
+set "vsdevcmd_arch="
+if /I "%target_platform%"=="x86" set "vsdevcmd_arch=x86"
+if /I "%target_platform%"=="x64" set "vsdevcmd_arch=x64"
+if /I "%target_platform%"=="arm64" set "vsdevcmd_arch=arm64"
+
+if "%vsdevcmd_arch%"=="" (
+ echo Unsupported target platform "%target_platform%". Expected one of: x86, x64, arm64.
+ exit /b 1
+)
+
+set "vswhere_path=%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe"
+set "vs_install_path="
+
+if exist "%vswhere_path%" for /f "usebackq delims=" %%i in (`"%vswhere_path%" -latest -products * -property installationPath`) do set "vs_install_path=%%i"
+if "%vs_install_path%"=="" if exist "%vswhere_path%" for /f "usebackq delims=" %%i in (`"%vswhere_path%" -latest -prerelease -products * -property installationPath`) do set "vs_install_path=%%i"
+if "%vs_install_path%"=="" if exist "%vswhere_path%" for /f "usebackq delims=" %%i in (`"%vswhere_path%" -all -products * -property installationPath`) do if "%vs_install_path%"=="" set "vs_install_path=%%i"
+
+if not "%VSCMD_VER%"=="" goto :resolve_msbuild
+
+if not exist "%vswhere_path%" (
+ echo Could not find vswhere at "%vswhere_path%".
+ exit /b 1
+)
+
+if "%vs_install_path%"=="" (
+ echo Could not locate a Visual Studio installation.
+ exit /b 1
+)
+
+set "vsdevcmd_path=%vs_install_path%\Common7\Tools\VsDevCmd.bat"
+if not exist "%vsdevcmd_path%" (
+ echo Could not find VsDevCmd.bat at "%vsdevcmd_path%".
+ exit /b 1
+)
+
+call "%vsdevcmd_path%" -no_logo -startdir=none -host_arch=x64 -arch=%vsdevcmd_arch%
+if errorlevel 1 (
+ echo VsDevCmd failed for target "%target_platform%".
+ exit /b 1
+)
+
+:resolve_msbuild
+set "resolved_msbuild=msbuild"
+where msbuild >nul 2>&1
+if not errorlevel 1 goto :set_msbuild
+
+if not "%vs_install_path%"=="" set "resolved_msbuild=%vs_install_path%\MSBuild\Current\Bin\MSBuild.exe"
+if exist "%resolved_msbuild%" goto :set_msbuild
+
+if not exist "%vswhere_path%" (
+ echo Could not find msbuild in PATH and could not find vswhere at "%vswhere_path%".
+ exit /b 1
+)
+
+set "resolved_msbuild="
+for /f "usebackq delims=" %%i in (`"%vswhere_path%" -latest -products * -find MSBuild\Current\Bin\MSBuild.exe`) do set "resolved_msbuild=%%i"
+
+if "%resolved_msbuild%"=="" (
+ echo Could not locate MSBuild.exe.
+ exit /b 1
+)
+
+:set_msbuild
+set "MSBUILD_CMD=%resolved_msbuild%"
+exit /b 0