$npx -y skills add microsoft/win-dev-skills --skill winui-setupInstall and verify the prerequisites the win-dev-skills WinUI 3 toolchain depends on — .NET SDK 10, the WinApp CLI, the WinUI 3 .NET templates, and Developer Mode. Use when setting up a new machine, after a Windows reset, or when another winui skill reports a missing prerequisite
| 1 | ### Purpose |
| 2 | |
| 3 | Install and verify the prerequisites every other `winui-*` skill assumes are already present on the machine. |
| 4 | |
| 5 | This skill is **idempotent** — every step checks first, skips if already satisfied, prints `[OK] already installed` and moves on. Re-running on a fully set-up machine is a fast no-op. |
| 6 | |
| 7 | ### Steps |
| 8 | |
| 9 | The first thing to do is **batch all detection up front** — run every check in parallel/together so you can show the user the full picture before installing anything. Then install only what's missing. |
| 10 | |
| 11 | #### Detect everything |
| 12 | |
| 13 | Run all of these together; collect the results: |
| 14 | |
| 15 | ```powershell |
| 16 | # .NET SDK — accept any installed SDK >= 8.0 |
| 17 | $dotnetSdks = (& dotnet --list-sdks 2>$null) -replace ' \[.*$','' |
| 18 | $dotnetOk = $dotnetSdks | ForEach-Object { [version]($_ -split '-')[0] } | |
| 19 | Where-Object { $_.Major -ge 8 } | Select-Object -First 1 |
| 20 | |
| 21 | # WinApp CLI — needs to be present AND >= 0.3 |
| 22 | $winappVersion = $null |
| 23 | $winappOk = $false |
| 24 | $winappCmd = Get-Command winapp -ErrorAction SilentlyContinue |
| 25 | if ($winappCmd) { |
| 26 | $raw = (& winapp --version 2>$null) -as [string] |
| 27 | if ($raw) { |
| 28 | $base = ($raw -split '-')[0] # strip "-prerelease.N" if present |
| 29 | try { |
| 30 | $winappVersion = [version]$base |
| 31 | $winappOk = $winappVersion -ge [version]'0.3' |
| 32 | } catch {} |
| 33 | } |
| 34 | } |
| 35 | |
| 36 | # WinUI 3 templates |
| 37 | $templatesOk = [bool](dotnet new list winui 2>$null | Select-String 'winui-mvvm' -Quiet) |
| 38 | |
| 39 | # Developer Mode |
| 40 | $devModeOk = ((Get-ItemProperty ` |
| 41 | -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock' ` |
| 42 | -Name AllowDevelopmentWithoutDevLicense -ErrorAction SilentlyContinue |
| 43 | ).AllowDevelopmentWithoutDevLicense) -eq 1 |
| 44 | ``` |
| 45 | |
| 46 | Print a one-shot status table so the user sees what you're about to do: |
| 47 | |
| 48 | ``` |
| 49 | .NET SDK ≥ 8 ✅ found 10.0.100 (or ❌ missing — will install Microsoft.DotNet.SDK.10) |
| 50 | WinApp CLI ⚠ found 0.3.1 — will upgrade to latest |
| 51 | (or ❌ missing/too old — will install Microsoft.WinAppCLI) |
| 52 | WinUI 3 templates ✅ found — will reinstall to make sure they're at latest |
| 53 | Developer Mode ❌ disabled — needs admin to enable |
| 54 | ``` |
| 55 | |
| 56 | > **Always upgrade WinApp CLI and the WinUI templates** even when they're already present — they ship breaking changes between releases and the rest of the `winui-*` skills assume latest. The minimum bar is "WinApp CLI ≥ 0.3 and templates installed at all"; the goal is "both at latest". |
| 57 | |
| 58 | #### Install what's missing |
| 59 | |
| 60 | Skip anything already-OK from detection. The remaining steps: |
| 61 | |
| 62 | ##### .NET SDK (only if no SDK ≥ 8.0 was found) |
| 63 | |
| 64 | ```powershell |
| 65 | winget install --id Microsoft.DotNet.SDK.10 --exact --silent --accept-package-agreements --accept-source-agreements |
| 66 | ``` |
| 67 | |
| 68 | `.NET 8.0` is the floor. If the user already has 8.0, 9.0, or 10.0 installed (any patch), the requirement is met — do not install another SDK side-by-side. |
| 69 | |
| 70 | ##### WinApp CLI — install if missing/old, then always upgrade |
| 71 | |
| 72 | If `$winappOk` is false (missing or `< 0.3`), install it. Then **always** run `winget upgrade` regardless, so even already-present installs get bumped to latest: |
| 73 | |
| 74 | ```powershell |
| 75 | # Install only if missing or too old |
| 76 | winget install --id Microsoft.WinAppCLI --exact --silent --accept-package-agreements --accept-source-agreements |
| 77 | |
| 78 | # Always — upgrade to latest (no-op if already at latest) |
| 79 | winget upgrade --id Microsoft.WinAppCLI --exact --silent --accept-package-agreements --accept-source-agreements |
| 80 | ``` |
| 81 | |
| 82 | ##### Refresh `$env:Path` |
| 83 | |
| 84 | If you installed the .NET SDK or anything else via winget in this session, **refresh PATH** so subsequent steps can find the new tools. Without this, `dotnet new install` will fail with "command not found" even though the SDK is on disk: |
| 85 | |
| 86 | ```powershell |
| 87 | $env:Path = [Environment]::GetEnvironmentVariable('Path','Machine') + ';' + [Environment]::GetEnvironmentVariable('Path','User') |
| 88 | ``` |
| 89 | |
| 90 | ##### WinUI 3 .NET templates — always reinstall to get latest |
| 91 | |
| 92 | Run this every time, whether or not `$templatesOk` was true. `dotnet new install` against an already-installed template package upgrades it in place to the latest version: |
| 93 | |
| 94 | ```powershell |
| 95 | dotnet new install Microsoft.WindowsAppSDK.WinUI.CSharp.Templates |
| 96 | ``` |
| 97 | |
| 98 | ##### Developer Mode (ask the user first!) |
| 99 | |
| 100 | Developer Mode is the DWORD `AllowDevelopmentWithoutDevLicense` under `HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock`. Setting it requires admin, which means a UAC prompt will pop up. **Do not just trigger UAC out of nowhere — ask the user first** so they're not surprised by the elevation prompt. Use |