X-Git-Url: https://vilimpoc.org/repos/dotfiles/blobdiff_plain/0b4125206461c1a63a971ac9cf503319bcb05798..325b494c6241dcc4dc1cb7436ee84ac105b318eb:/setup-windows-steps.ps1?ds=sidebyside diff --git a/setup-windows-steps.ps1 b/setup-windows-steps.ps1 index 02c1515..765bb37 100644 --- a/setup-windows-steps.ps1 +++ b/setup-windows-steps.ps1 @@ -15,8 +15,9 @@ setup-windows-no-uac.ps1 takes the 'user' steps - per-user configuration THIS IS THE ONE PLACE a step's availability is decided. -X64Only, with its - reason, keeps a step off ARM64; -Admin keeps it off an account that cannot - elevate. The planner shows both as "[-]" rows with the reason, the batch file + reason, keeps a step off ARM64; -NotInVM, with its reason, keeps it off a + Windows that is itself a virtual machine; -Admin keeps it off an account that + cannot elevate. The planner shows each as a "[-]" row with the reason, the batch file prints the same reason in the log where the step would have run, and the two halves apply them again when run on their own. This replaces the :x64only subroutine that used to sit at the bottom of setup-windows.bat and the @@ -51,6 +52,9 @@ function New-SetupStep { [string] $Package, # Not on ARM64, because . Shown in the plan and in the run log. [string] $X64Only, + # Not when this Windows is a guest in a virtual machine, because . + # Shown in the plan and in the run log, like -X64Only. + [string] $NotInVM, # Needs an account that can elevate: a machine-wide installer, or part # of the elevated half. [switch] $Admin, @@ -66,6 +70,7 @@ function New-SetupStep { Text = $shown Package = $Package X64Only = $X64Only + NotInVM = $NotInVM Admin = [bool]$Admin Needs = $Needs } @@ -115,13 +120,16 @@ function Get-SetupCatalog { New-SetupStep NASM U bat -Package NASM.NASM ` -X64Only 'x86/x64-only assembler; MSVC armasm64 is the native one' New-SetupStep VirtualBox U bat -Package Oracle.VirtualBox -Text 'for the Windows 7 test VM' ` - -X64Only 'no ARM64 host build, so no Windows 7 x86 test VM either' + -X64Only 'no ARM64 host build, so no Windows 7 x86 test VM either' ` + -NotInVM 'the test VMs belong on the physical host, not nested in a guest' # --- setup-windows.bat: machine-wide installers, despite running unelevated --- New-SetupStep DotNetSdk M bat -Admin -Package Microsoft.DotNet.SDK.10 -Text 'for the WiX tooling' New-SetupStep CMake M bat -Admin -Package Kitware.CMake -Text 'standalone, so a plain cmake works in any shell' New-SetupStep AndroidGPUInspector M bat -Admin -Package Google.AndroidGPUInspector ` -X64Only 'x64-only build, and it profiles Android devices, not this box' + New-SetupStep AndroidStudio M bat -Admin -Package Google.AndroidStudio -Text 'only if missing; it updates itself' ` + -X64Only 'Google publishes no Windows ARM64 build of Android Studio' New-SetupStep OpenCppCoverage M bat -Admin -Package OpenCppCoverage.OpenCppCoverage -Text 'native line coverage' ` -X64Only 'it steps x86/x64 instructions, so it cannot cover an ARM64 binary' New-SetupStep WiX M bat -Needs DotNetSdk ` @@ -143,6 +151,8 @@ function Get-SetupCatalog { New-SetupStep VTune E uac -Admin -Text 'Intel VTune Profiler: report whether it is installed (installs nothing)' # --- setup-windows-no-uac.ps1: per-user configuration --- + # First, so the PATH it fixes is in place before anything reports on it. + New-SetupStep LocalBinPath C user -Text '%USERPROFILE%\.local\bin on the user PATH (where Claude Code''s launcher lives)' New-SetupStep WinMergePath C user -Needs WinMerge -Text 'WinMerge on the user PATH' ` -X64Only 'WinMerge is not installed on ARM64' New-SetupStep VsWhere C user -Needs VisualStudio -Text 'vswhere.exe on the user PATH' @@ -153,6 +163,9 @@ function Get-SetupCatalog { New-SetupStep LlvmPath C user -Needs LLVM -Text 'upstream LLVM on the user PATH' ` -X64Only 'LLVM is not installed on ARM64' New-SetupStep RustToolchain C user -Needs Rustup, VisualStudio -Text $rust + New-SetupStep AndroidSdk C user -Needs AndroidStudio ` + -Text 'Android SDK, per-user: latest platform + build-tools; accepts the SDK licences' ` + -X64Only 'its Windows build tools are x86/x64 only, as is Android Studio' New-SetupStep ArchAudit C user -Text 'architecture audit: native or emulated, for every tool (read-only)' # --- setup-windows.bat, after both halves --- @@ -163,15 +176,54 @@ function Get-SetupCatalog { function Get-SetupStepBlocker { # Why this step cannot run on this machine at all, or $null if it can. # Architecture first: an x64-only step is off ARM64 before elevation is even - # consulted, which is the more useful reason to show. - param($Step, [bool] $IsArm64, [string] $Elevation) + # consulted, which is the more useful reason to show. Then the machine + # itself, then the account. + param($Step, [bool] $IsArm64, [string] $Elevation, [string] $VirtualMachine) if ($IsArm64 -and $Step.X64Only) { return "not on ARM64 - $($Step.X64Only)" } + if ($VirtualMachine -and $Step.NotInVM) { + return "not in a virtual machine ($VirtualMachine) - $($Step.NotInVM)" + } if ($Elevation -eq 'NOLUA' -and $Step.Admin) { return 'needs an administrator - this account cannot elevate' } $null } +function Get-SetupVirtualMachine { + # The hypervisor this Windows is running under as a guest, by name, or $null + # on physical hardware. + # + # Read from the SMBIOS strings the firmware reports - Win32_ComputerSystem's + # Manufacturer and Model - which every common hypervisor fills in with its own + # name. NOT from HypervisorPresent: that is true on a PHYSICAL box too as soon + # as Hyper-V, WSL2, Windows Sandbox or virtualization-based security is on, + # which is most Windows 11 machines - the host OS then runs in the root + # partition, above a hypervisor, without being anyone's guest. + # + # A lookup that fails says "physical": this only ever takes steps away, and a + # step wrongly offered on a VM is one you can switch off in the plan. + $cs = Get-CimInstance Win32_ComputerSystem -ErrorAction SilentlyContinue + if (-not $cs) { return $null } + $smbios = "$($cs.Manufacturer) | $($cs.Model)" + # Hyper-V's pair is matched whole: Microsoft is also the manufacturer of + # every Surface, and "Virtual Machine" is the model only in a guest. Azure + # guests report the same pair. + $known = [ordered]@{ + 'innotek|VirtualBox' = 'VirtualBox' + 'VMware' = 'VMware' + '^Microsoft Corporation \| Virtual Machine$' = 'Hyper-V' + 'QEMU|KVM|Bochs' = 'QEMU/KVM' + 'Parallels' = 'Parallels' + '\bXen\b|HVM domU' = 'Xen' + 'Amazon EC2' = 'Amazon EC2' + 'Google Compute Engine' = 'Google Compute Engine' + } + foreach ($pattern in $known.Keys) { + if ($smbios -match $pattern) { return $known[$pattern] } + } + $null +} + function Split-SetupNames { # `powershell -File` hands a whole "A,B,C" to an array parameter as ONE # string, so split here and accept either spelling. @@ -207,13 +259,16 @@ function Resolve-SetupSelection { [string[]] $Skip = @(), [hashtable] $Aliases = @{}, [bool] $IsArm64, - [string] $Elevation + [string] $Elevation, + # The hypervisor's name when this Windows is a guest (see + # Get-SetupVirtualMachine), $null or empty on physical hardware. + [string] $VirtualMachine ) $want = if ($null -eq $Only) { @($Steps.Id) } else { @(Resolve-SetupStepNames $Only $Steps $Aliases) } $drop = @(Resolve-SetupStepNames $Skip $Steps $Aliases) $named = @(Split-SetupNames $Only | ForEach-Object { if ($Aliases.ContainsKey($_)) { $Aliases[$_] } else { $_ } }) foreach ($s in $Steps) { - $why = Get-SetupStepBlocker $s $IsArm64 $Elevation + $why = Get-SetupStepBlocker $s $IsArm64 $Elevation $VirtualMachine if ($why -and $named -contains $s.Id) { Write-Warning "$($s.Id) was asked for but cannot run here: $why" }