@echo off @rem --------------------------------------------------------------------------- @rem setup-windows.bat - provision a fresh Windows box for native development @rem --------------------------------------------------------------------------- @rem --- Non-admin (per-user) winget installs --- winget install Anthropic.ClaudeCode winget install Git.Git winget install Microsoft.DotNet.SDK.10 winget install Microsoft.PowerShell Microsoft.Sysinternals.ProcessExplorer Microsoft.Sysinternals.ProcessMonitor Microsoft.Sysinternals.SDelete Microsoft.VisualStudioCode Microsoft.WindowsTerminal winget install Oracle.VirtualBox winget install Python.Python.3.13 winget install WinMerge.WinMerge @rem OpenCppCoverage: native (PE) line coverage for the C++ binaries. run-coverage-occ.py drives the @rem pytest suite under it to produce an HTML report (the binaries under test build with PDBs, @rem which it reads). The installer elevates via UAC. winget install OpenCppCoverage.OpenCppCoverage @rem --- WiX 5.0.2, pinned on purpose --- @rem WiX packages our proprietary software into MSIs, and the version is pinned to keep that @rem free of a fee. 5.0.2 is the last release distributed under the Microsoft Reciprocal @rem License alone. From 6.0 onward the package also carries OSMFEULA.txt, an Open Source @rem Maintenance Fee agreement: a monthly fee owed by anyone who uses the PREBUILT BINARIES @rem as part of revenue-generating activity and has annual gross revenue >= US$10,000. @rem @rem It is a fee for the binaries, not a restriction on what we ship - MS-RL is file-scoped @rem and never reached the MSIs WiX builds, under any version - but 5.0.2 owes nothing. @rem The 6.x/7.x SOURCE is still MS-RL too, so self-compiling is another way out; a pin is @rem the cheaper one. This replaces `winget install WiXToolset.WiXCLI`, which has no version @rem selector and so installs the latest (7.0.0 today, EULA and all). @rem @rem PIN THE MSBUILD SIDE TOO. A .wixproj referencing WixToolset.Sdk without a version @rem resolves to the latest - 7.x, same EULA - and nothing here constrains it. Pin it in the @rem project: . @rem @rem dotnet.exe is called by full path: winget put the SDK on the machine PATH a few lines @rem ago, but this cmd session inherited its environment before that and cannot see it. @rem install-then-update is for re-runs - install fails once the tool is there, and update @rem then holds it at exactly 5.0.2 - which keeps this script idempotent like the rest. set "DOTNET_EXE=%ProgramFiles%\dotnet\dotnet.exe" "%DOTNET_EXE%" tool install --global wix --version 5.0.2 || "%DOTNET_EXE%" tool update --global wix --version 5.0.2 @rem Report what the pin actually produced. By full path again, and because the shim lands in @rem a directory this session's PATH predates: expect "5.0.2+", not 7.x. "%USERPROFILE%\.dotnet\tools\wix.exe" --version @rem --------------------------------------------------------------------------- @rem No package manager needed for the Windows build @rem @rem Just: @rem cd windows && cmake -B build -G "Visual Studio 17 2022" -A x64 && cmake --build build --config Release @rem --------------------------------------------------------------------------- @rem --- Elevated installs (VS2022, WDK, system tools) --- @rem The elevated script runs in its own window and logs to setup-windows-uac.log. @rem -PassThru + $p.ExitCode propagates its real exit code back through to ERRORLEVEL. @rem @rem -TraceUser passes YOU across the UAC boundary. Accepting that prompt with an @rem administrator's credentials runs the elevated half AS that administrator, so @rem it cannot see whose box this is; the account named here is the one it grants @rem non-elevated ETW collection rights to (xperf / wpr without a UAC prompt). set "UAC_LOG=%~dp0setup-windows-uac.log" if exist "%UAC_LOG%" del "%UAC_LOG%" powershell -NoProfile -Command "$p = Start-Process powershell -Verb RunAs -ArgumentList '-NoProfile','-ExecutionPolicy','Bypass','-File','""%~dp0setup-windows-with-uac.ps1""','-TraceUser','""%USERDOMAIN%\%USERNAME%""' -Wait -PassThru; exit $p.ExitCode" set "UAC_RC=%ERRORLEVEL%" @rem --- Surface the elevated session's output (its window has already closed) --- if exist "%UAC_LOG%" ( echo. echo ===== elevated setup log ^(%UAC_LOG%^) ===== type "%UAC_LOG%" echo ===== end of elevated setup log ===== ) else ( echo [setup-windows] WARNING: no elevated log found at "%UAC_LOG%". echo [setup-windows] The elevated window may have been cancelled at the UAC prompt. ) @rem --- Non-elevated PowerShell half --- @rem WinMerge on the user PATH, BinSkim, and the global git config (identity + @rem core.sshCommand -> a Win32-OpenSSH client, so git shares the Windows @rem ssh-agent). EDIT THE GIT IDENTITY at the top of setup-windows-no-uac.ps1 @rem before the first run. @rem @rem Deliberately NOT elevated: every step writes per-user state (the HKCU PATH, @rem the .gitconfig under %USERPROFILE%), which the elevated half would write to @rem the administrator profile instead. @rem @rem AFTER the elevated half on purpose: core.sshCommand prefers the ssh.exe that @rem half unpacks beside rsync.exe - a push through the in-box client is capped @rem at ~17MB/s - and it can only prefer it once it is on disk. Run either way, @rem including when the elevated half failed above: nothing here depends on it, @rem and the fallback is the in-box client that Windows already has. @rem @rem Non-fatal: these are conveniences, and the elevated half is the part worth @rem the UAC prompt. A failure warns and provisioning continues. powershell -NoProfile -ExecutionPolicy Bypass -File "%~dp0setup-windows-no-uac.ps1" if not "%ERRORLEVEL%"=="0" echo [setup-windows] WARNING: setup-windows-no-uac.ps1 reported a failure ^(see above^); continuing. if not "%UAC_RC%"=="0" ( echo. echo [setup-windows] ELEVATED SETUP FAILED ^(exit code %UAC_RC%^). See log above. exit /b %UAC_RC% ) echo. echo [setup-windows] Elevated setup completed successfully. @rem Removed: this doesn't work as well as I hoped, maybe try again later @rem -- Install Headroom --- @rem py -m pip install "headroom-ai[all]" @rem npm install headroom-ai py -m pip install Pillow