X-Git-Url: https://vilimpoc.org/repos/dotfiles/blobdiff_plain/fbe899b67d263a1ae5404d3ed25f5f091c3d2c1e..cd774a195092cd0ab4c8e92862d0c5cf7e04f195:/setup-windows.bat diff --git a/setup-windows.bat b/setup-windows.bat index b9e4752..bd248a9 100644 --- a/setup-windows.bat +++ b/setup-windows.bat @@ -26,6 +26,31 @@ set "IS_ARM64=0" if /i "%HOST_ARCH%"=="ARM64" set "IS_ARM64=1" echo [setup-windows] Host architecture: %HOST_ARCH% +@rem --------------------------------------------------------------------------- +@rem Can this account elevate? Worked out ONCE, here, because it gates two very +@rem different things: the elevated half far below, and a handful of the "per-user" +@rem winget installs just after this, which are per-user in name only. +@rem +@rem ALREADY - already elevated. IsInRole(Administrator) is false for an admin +@rem running unelevated under UAC, so this means actually elevated, +@rem not merely capable of it. +@rem PROMPT - not elevated, UAC on, so elevation can be requested. +@rem NOLUA - UAC is off machine-wide (EnableLUA = 0) AND this is not an +@rem administrator. Elevation is impossible, not merely declined: +@rem Windows has no prompt to offer. Note that with UAC off, +@rem `Start-Process -Verb RunAs` does not fail - it is silently +@rem ignored, runs the child with the caller's own token, and reports +@rem success, which is why this needs detecting rather than trying. +@rem --------------------------------------------------------------------------- +set "ELEV=PROMPT" +for /f "usebackq tokens=*" %%A in (`powershell -NoProfile -ExecutionPolicy Bypass -Command "$id=[Security.Principal.WindowsIdentity]::GetCurrent(); if (([Security.Principal.WindowsPrincipal]$id).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) { 'ALREADY' } elseif ((Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System' -ErrorAction SilentlyContinue).EnableLUA -eq 0) { 'NOLUA' } else { 'PROMPT' }"`) do set "ELEV=%%A" +echo [setup-windows] Elevation: %ELEV% +if "%ELEV%"=="NOLUA" ( + echo [setup-windows] This account cannot elevate ^(UAC off, not an administrator^). Packages that + echo [setup-windows] need a machine-wide install will be SKIPPED rather than left to fail; details + echo [setup-windows] at each one, and a summary before the elevated half. +) + @rem --- Non-admin (per-user) winget installs --- @rem @rem No --architecture anywhere on purpose. winget already picks the best @@ -44,7 +69,6 @@ echo [setup-windows] Host architecture: %HOST_ARCH% winget install Anthropic.ClaudeCode winget install Brave.Brave 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 Python.Python.3.13 @@ -87,7 +111,10 @@ if "%IS_ARM64%"=="1" ( @rem PATH, behind every machine and user entry. setup-windows-no-uac.ps1 then @rem pins the native ninja's directory to the FRONT of the user PATH so the @rem margin does not depend on two append orders staying as they are. -winget install Kitware.CMake +@rem +@rem Ninja here, CMake in the machine-wide group below: Ninja is a portable zip +@rem winget unpacks into the user profile, CMake is an MSI that installs for the +@rem whole machine. winget install Ninja-build.Ninja @rem --- Second, independent Clang: compiler diversity --- @@ -109,12 +136,10 @@ winget install Ninja-build.Ninja @rem -DCMAKE_CXX_COMPILER with a full path when you care. winget install LLVM.LLVM -@rem x64-only manifests: winget falls back to the x64 installer on ARM64 and these -@rem run under Prism emulation. Harmless for what they do here - iperf3 is a -@rem network benchmark bounded by the link, and AGI is an Android-side GPU -@rem profiler whose work happens on the phone. Neither is CPU-bound on this box. +@rem x64-only manifest: winget falls back to the x64 installer on ARM64 and it runs +@rem under Prism emulation. Harmless for what it does here - iperf3 is a network +@rem benchmark bounded by the link, not by CPU. winget install ar51an.iPerf3 -winget install Google.AndroidGPUInspector @rem NASM assembles x86/x86-64 only - there is no ARM64 target in it and no ARM64 @rem build of it. Installed on ARM64 anyway (as emulated x64) because this box @@ -138,6 +163,38 @@ if "%IS_ARM64%"=="1" ( winget install Oracle.VirtualBox ) +@rem --------------------------------------------------------------------------- +@rem Machine-wide installers, despite sitting in the "per-user" section +@rem +@rem These four are not per-user at all. On an account that cannot elevate they +@rem fail on every run, with installer exit codes that say nothing useful: +@rem Microsoft.DotNet.SDK.10 exit 5 (ERROR_ACCESS_DENIED) +@rem Kitware.CMake exit 1603 (generic MSI failure) +@rem Google.AndroidGPUInspector exit 1603 +@rem OpenCppCoverage exit 1 (its installer self-elevates) +@rem +@rem Grouped and skipped outright where elevation is impossible. Attempting a +@rem guaranteed failure four times per run - and paying the download for it - +@rem teaches nobody anything, and the four opaque error codes bury the one line +@rem that matters. On an account that can elevate they run exactly as before. +@rem +@rem NOTE none of these is a build-blocker: the .NET SDK is only here for the WiX +@rem MSI tooling, CMake also ships inside Visual Studio, AGI profiles Android +@rem devices, and OpenCppCoverage cannot instrument ARM64 binaries anyway. +@rem --------------------------------------------------------------------------- +if "%ELEV%"=="NOLUA" ( + echo. + echo [setup-windows] Skipping the machine-wide installers - this account cannot elevate: + echo [setup-windows] Microsoft.DotNet.SDK.10, Kitware.CMake, Google.AndroidGPUInspector, OpenCppCoverage. + echo [setup-windows] None blocks a build. Re-run from an administrator account to get them. + echo. + goto :after_admin_pkgs +) + +winget install Microsoft.DotNet.SDK.10 +winget install Kitware.CMake +winget install Google.AndroidGPUInspector + @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. @@ -148,6 +205,8 @@ if "%IS_ARM64%"=="1" ( @rem cross-compiles but NOT an ARM64 one. For ARM64 coverage, build the ARM64 @rem binaries with /fsanitize-coverage or use the x64 build for the coverage run. winget install OpenCppCoverage.OpenCppCoverage + +:after_admin_pkgs if "%IS_ARM64%"=="1" echo [setup-windows] NOTE: OpenCppCoverage is x86/x64-only - it cannot instrument ARM64 binaries. Run coverage against the x64 build. @rem --- WiX 5.0.2, pinned on purpose --- @@ -214,10 +273,51 @@ if not exist "%DOTNET_EXE%" goto :after_wix set "UAC_LOG=%~dp0setup-windows-uac.log" if exist "%UAC_LOG%" del "%UAC_LOG%" +@rem %ELEV% was worked out at the top of this script - see the comment there for +@rem why `Start-Process -Verb RunAs` cannot be trusted to report this itself. +if "%ELEV%"=="NOLUA" goto :elev_impossible +if "%ELEV%"=="ALREADY" goto :elev_direct + +@rem Not elevated, UAC is on: request it. Expect a prompt. +echo [setup-windows] Requesting elevation ^(expect a UAC prompt^)... powershell -NoProfile -Command "$p = Start-Process powershell -Verb RunAs -ArgumentList '-NoProfile','-ExecutionPolicy','Bypass','-File','""%~dp0setup-windows-with-uac.ps1""' -Wait -PassThru; exit $p.ExitCode" set "UAC_RC=%ERRORLEVEL%" +goto :elev_done + +:elev_direct +echo [setup-windows] Already running elevated; running the elevated half directly. +powershell -NoProfile -ExecutionPolicy Bypass -File "%~dp0setup-windows-with-uac.ps1" +set "UAC_RC=%ERRORLEVEL%" +goto :elev_done + +:elev_impossible +echo. +echo [setup-windows] SKIPPING the elevated half: this account cannot elevate. +echo [setup-windows] UAC is disabled machine-wide ^(EnableLUA = 0^) and you are not an administrator, +echo [setup-windows] so Windows offers no way to elevate - there is no prompt to accept. With UAC off, +echo [setup-windows] 'Start-Process -Verb RunAs' is silently ignored and reports success, which is why +echo [setup-windows] this used to look like a cancelled prompt. +echo [setup-windows] +echo [setup-windows] Not installed: Visual Studio components ^(including clang-cl^), the WDK, +echo [setup-windows] rsync, and the OpenSSH server. Everything per-user above is unaffected. +echo [setup-windows] +echo [setup-windows] To finish the box, either sign in to an administrator account and re-run this +echo [setup-windows] script, or have an administrator run setup-windows-with-uac.ps1 there. Then +echo [setup-windows] re-run setup-windows-no-uac.ps1 as yourself, so the per-user PATH and .gitconfig +echo [setup-windows] land in YOUR profile rather than the administrator's. +echo. +set "UAC_RC=SKIPPED" + +:elev_done @rem --- Surface the elevated session's output (its window has already closed) --- +@rem +@rem A missing log is NOT self-explanatory, so do not guess at one cause. The +@rem elevated script writes its transcript as almost its first act, so no log +@rem means it never got as far as running: either the prompt was declined, or it +@rem started unelevated and stopped on its own #Requires line. Which of those it +@rem was is already known from %ELEV%, so report that instead of speculating. +if "%UAC_RC%"=="SKIPPED" goto :after_uac_log if exist "%UAC_LOG%" ( echo. echo ===== elevated setup log ^(%UAC_LOG%^) ===== @@ -225,8 +325,10 @@ if exist "%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. + if "%ELEV%"=="PROMPT" echo [setup-windows] The elevated window never started - the UAC prompt was most likely declined. + if "%ELEV%"=="ALREADY" echo [setup-windows] The elevated half exited before writing its transcript; see its output above. ) +:after_uac_log @rem --- Non-elevated PowerShell half --- @rem WinMerge on the user PATH, BinSkim, and the global git config (identity + @@ -249,6 +351,11 @@ if exist "%UAC_LOG%" ( 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. +@rem Skipping the elevated half is a reported, understood outcome on a box where +@rem elevation is impossible - not a failure to exit non-zero over. The per-user +@rem provisioning above did run, and re-running from an administrator account is +@rem the documented next step. +if "%UAC_RC%"=="SKIPPED" goto :uac_reported if not "%UAC_RC%"=="0" ( echo. echo [setup-windows] ELEVATED SETUP FAILED ^(exit code %UAC_RC%^). See log above. @@ -256,6 +363,11 @@ if not "%UAC_RC%"=="0" ( ) echo. echo [setup-windows] Elevated setup completed successfully. +goto :uac_reported + +:uac_reported +if "%UAC_RC%"=="SKIPPED" echo. +if "%UAC_RC%"=="SKIPPED" echo [setup-windows] Per-user setup complete; the elevated half was skipped ^(see above^). @rem Removed: this doesn't work as well as I hoped, maybe try again later @rem -- Install Headroom --- @@ -280,3 +392,10 @@ if "%IS_ARM64%"=="1" ( echo [setup-windows] unavailable : VirtualBox, the Windows 7 x86 test VM, Intel VTune, echo [setup-windows] and the v141 / Windows XP targeting toolset. ) +@rem The list above is what this script PROVIDES on ARM64, not necessarily what +@rem landed on this run - so point at the audit, which reports the actual state. +if "%ELEV%"=="NOLUA" ( + echo [setup-windows] NOT on this box: everything needing elevation was skipped, including + echo [setup-windows] Visual Studio's clang-cl, the .NET SDK and CMake. The + echo [setup-windows] architecture audit above lists what is really installed. +)