diff --git a/CHANGELOG.md b/CHANGELOG.md
index 476c3ee..4083d68 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,47 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
+## [1.0.12] - 2026-05-05
+
+### Fixed
+- **".NET must be installed" startup failure**: PassKey v1.0.11 showed "You must install
+ or update .NET to run this application" because the bundled `.NET 10.0.7` installer
+ was failing silently during setup (likely due to a pre-existing .NET 8/9 installation
+ triggering an incorrect skip condition). The fix switches `PassKey.Desktop` back to
+ **self-contained** publishing: the .NET runtime is now bundled directly in the
+ application folder, so no separate .NET installer is required. The `.NET 10.0.7`
+ redistributable has been removed from the installer entirely.
+ Windows App Runtime 1.8.260416003 (introduced in v1.0.11) is still bundled and
+ continues to address the Windows 11 25H2 STATUS_INVALID_IMAGE_HASH crash.
+
+## [1.0.11] - 2026-05-04
+
+### Fixed
+- **Windows 11 25H2 crash (STATUS_INVALID_IMAGE_HASH — Windows App Runtime 1.8.260101001)**:
+ PassKey v1.0.10 crashed on Windows 11 25H2 (Build 26200+) with exception code `0xc000027b`
+ in `Microsoft.UI.Xaml.dll` even with the system-installed Windows App Runtime 1.8.
+ The root cause is a compatibility bug in Windows App Runtime **1.8.260101001** with
+ Windows 11 25H2. The fix upgrades the bundled Windows App Runtime installer and the NuGet SDK
+ from `1.8.260101001` to **1.8.260416003** (released 21 April 2026).
+
+## [1.0.10] - 2026-05-04
+
+### Fixed
+- **Windows 11 25H2 crash (STATUS_INVALID_IMAGE_HASH — self-contained .NET)**: PassKey v1.0.9
+ crashed on Windows 11 25H2 (Build 26200+) because the self-contained .NET 10 apphost
+ triggers a WinRT activation incompatibility with the Windows App Runtime framework package:
+ `Microsoft.UI.Xaml.dll` throws `STATUS_INVALID_IMAGE_HASH` internally. The same crash
+ was reproducible on clean VirtualBox VMs with no third-party security software, confirming
+ the root cause is a Windows 11 25H2-specific behaviour.
+
+ The fix switches `PassKey.Desktop` to **framework-dependent** publishing
+ (`--self-contained false`). The installer now bundles and silently installs the
+ **.NET 10.0.7 Runtime** (29 MB, from `builds.dotnet.microsoft.com`) before launching
+ PassKey, so end users still do not need to install .NET manually.
+
+ The `BrowserHost` component remains self-contained (single-file executable, unaffected
+ by the WinRT issue).
+
## [1.0.9] - 2026-05-04
### Fixed
@@ -148,7 +189,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- **Giuseppe Imperato** — concept, design, product decisions
- **[Claude](https://www.anthropic.com/claude) by Anthropic** — architecture, implementation, documentation
-[Unreleased]: https://github.com/pexatar/PassKey/compare/v1.0.9...HEAD
+[Unreleased]: https://github.com/pexatar/PassKey/compare/v1.0.12...HEAD
+[1.0.12]: https://github.com/pexatar/PassKey/compare/v1.0.11...v1.0.12
+[1.0.11]: https://github.com/pexatar/PassKey/compare/v1.0.10...v1.0.11
+[1.0.10]: https://github.com/pexatar/PassKey/compare/v1.0.9...v1.0.10
[1.0.9]: https://github.com/pexatar/PassKey/compare/v1.0.8...v1.0.9
[1.0.8]: https://github.com/pexatar/PassKey/compare/v1.0.7...v1.0.8
[1.0.7]: https://github.com/pexatar/PassKey/compare/v1.0.6...v1.0.7
diff --git a/Installer/Download-Runtime.ps1 b/Installer/Download-Runtime.ps1
index 1c229b2..88c821b 100644
--- a/Installer/Download-Runtime.ps1
+++ b/Installer/Download-Runtime.ps1
@@ -1,19 +1,28 @@
# Download-Runtime.ps1
-# Downloads the Windows App Runtime 1.8.260101001 redistributable required to
-# build the PassKey installer. The file is excluded from git (> 100 MB limit).
+# Downloads the redistributables required to build the PassKey installer.
+# Both files are excluded from git (> 100 MB for WindowsAppRuntime, consistency for .NET).
#
# Usage: .\Installer\Download-Runtime.ps1
# Run once before building the installer with Inno Setup.
-$url = "https://aka.ms/windowsappsdk/1.8/1.8.260101001/windowsappruntimeinstall-x64.exe"
-$output = Join-Path $PSScriptRoot "WindowsAppRuntimeInstall-x64.exe"
+$files = @(
+ @{
+ Url = "https://aka.ms/windowsappsdk/1.8/1.8.260416003/windowsappruntimeinstall-x64.exe"
+ Output = Join-Path $PSScriptRoot "WindowsAppRuntimeInstall-x64.exe"
+ Label = "Windows App Runtime 1.8.7 (1.8.260416003)"
+ }
+ # Note: .NET runtime is no longer needed here.
+ # PassKey.Desktop is published self-contained — the .NET runtime is bundled
+ # in the application folder, so end users do not need .NET installed.
+)
-if (Test-Path $output) {
- Write-Host "Already present: $output" -ForegroundColor Green
- exit 0
+foreach ($f in $files) {
+ if (Test-Path $f.Output) {
+ Write-Host "Already present: $($f.Label)" -ForegroundColor Green
+ continue
+ }
+ Write-Host "Downloading $($f.Label)..." -ForegroundColor Cyan
+ Invoke-WebRequest -Uri $f.Url -OutFile $f.Output -UseBasicParsing
+ $sizeMB = [math]::Round((Get-Item $f.Output).Length / 1MB, 1)
+ Write-Host "Done — $sizeMB MB saved to: $($f.Output)" -ForegroundColor Green
}
-
-Write-Host "Downloading Windows App Runtime 1.8.260101001..." -ForegroundColor Cyan
-Invoke-WebRequest -Uri $url -OutFile $output -UseBasicParsing
-$sizeMB = [math]::Round((Get-Item $output).Length / 1MB, 1)
-Write-Host "Done — $sizeMB MB saved to: $output" -ForegroundColor Green
diff --git a/Installer/PassKey.iss b/Installer/PassKey.iss
index 7f83cbb..c5be3af 100644
--- a/Installer/PassKey.iss
+++ b/Installer/PassKey.iss
@@ -4,8 +4,8 @@
[Setup]
AppId={{A7F3C2D1-8E4B-4F9A-B6D5-3C1E7A2F0D84}
AppName=PassKey
-AppVersion=1.0.9
-AppVerName=PassKey 1.0.9
+AppVersion=1.0.12
+AppVerName=PassKey 1.0.12
AppPublisher=Giuseppe Imperato
AppPublisherURL=https://github.com/pexatar/PassKey
AppSupportURL=https://github.com/pexatar/PassKey/issues
@@ -21,10 +21,10 @@ SolidCompression=yes
ArchitecturesAllowed=x64compatible
ArchitecturesInstallIn64BitMode=x64os
MinVersion=10.0.17763
-PrivilegesRequired=lowest
-PrivilegesRequiredOverridesAllowed=dialog
+PrivilegesRequired=admin
UninstallDisplayIcon={app}\PassKey.Desktop.exe
WizardStyle=modern
+SetupLogging=yes
[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"
@@ -39,9 +39,9 @@ Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; Flags: unchecked
[Files]
; Windows App Runtime 1.8 redistributable — installed silently before the app launches.
-; HVCI (Hypervisor-Protected Code Integrity) rejects DLLs that are not in the Windows
-; Code Integrity system catalog. The official runtime installer registers trusted, cataloged
-; DLLs; the NuGet-bundled copies (WindowsAppSDKSelfContained) do not.
+; PassKey.Desktop is published self-contained (.NET bundled), so no separate .NET
+; installer is needed. The App Runtime provides Microsoft.UI.Xaml.dll and WinRT
+; support; it is loaded at runtime via Bootstrap.Initialize().
Source: "WindowsAppRuntimeInstall-x64.exe"; DestDir: "{tmp}"; Flags: ignoreversion deleteafterinstall
; Published self-contained output (Desktop + BrowserHost)
@@ -52,21 +52,15 @@ Name: "{group}\PassKey"; Filename: "{app}\PassKey.Desktop.exe"
Name: "{group}\{cm:UninstallProgram,PassKey}"; Filename: "{uninstallexe}"
Name: "{autodesktop}\PassKey"; Filename: "{app}\PassKey.Desktop.exe"; Tasks: desktopicon
-[Registry]
-; passkey:// URL scheme handler
-Root: HKCU; Subkey: "SOFTWARE\Classes\passkey"; ValueType: string; ValueData: "PassKey Protocol"; Flags: uninsdeletekey
-Root: HKCU; Subkey: "SOFTWARE\Classes\passkey"; ValueType: string; ValueName: "URL Protocol"; ValueData: ""; Flags: uninsdeletekey
-Root: HKCU; Subkey: "SOFTWARE\Classes\passkey\shell\open\command"; ValueType: string; ValueData: """{app}\PassKey.Desktop.exe"" ""%1"""; Flags: uninsdeletekey
-
-; Native Messaging Host for Chrome
-Root: HKCU; Subkey: "SOFTWARE\Google\Chrome\NativeMessagingHosts\com.passkey.host"; ValueType: string; ValueData: "{app}\com.passkey.host.json"; Flags: uninsdeletevalue
-
-; Native Messaging Host for Firefox
-Root: HKCU; Subkey: "SOFTWARE\Mozilla\NativeMessagingHosts\com.passkey.host"; ValueType: string; ValueData: "{app}\com.passkey.host.json"; Flags: uninsdeletevalue
+; Registry entries for passkey:// URL scheme and Native Messaging Hosts are NOT
+; written here. PassKey.Desktop.exe registers them in HKCU at first launch via
+; ProtocolActivationService.EnsureRegistered() — this avoids HKCU/HKLM conflicts
+; when the installer runs elevated and also keeps uninstall clean (app removes them
+; on uninstall).
[Run]
-; 1. Install Windows App Runtime 1.8 silently (waits for completion before continuing).
-; The installer is idempotent: if the runtime is already present it exits immediately.
+; 1. Install Windows App Runtime 1.8 silently.
+; Idempotent: exits immediately if the same or newer version is already present.
Filename: "{tmp}\WindowsAppRuntimeInstall-x64.exe"; Parameters: "--quiet"; \
StatusMsg: "Installing Windows App Runtime 1.8..."; \
Flags: waituntilterminated
diff --git a/README.md b/README.md
index e3ed0fd..bd16198 100644
--- a/README.md
+++ b/README.md
@@ -57,8 +57,8 @@ PassKey stores your passwords, credit cards, identities, and secure notes in a l
| Version | Platform | Type |
|---------|----------|------|
-| [v1.0.9](https://github.com/pexatar/PassKey/releases/tag/v1.0.9) | Windows x64 | Installer EXE |
-| [v1.0.9](https://github.com/pexatar/PassKey/releases/tag/v1.0.9) | Windows x64 | Portable ZIP |
+| [v1.0.12](https://github.com/pexatar/PassKey/releases/tag/v1.0.12) | Windows x64 | Installer EXE |
+| [v1.0.12](https://github.com/pexatar/PassKey/releases/tag/v1.0.12) | Windows x64 | Portable ZIP |
> **Requirements:** Windows 10 version 1809 (build 17763) or later, x64 processor.
> No .NET runtime required — PassKey is fully self-contained.
diff --git a/publish.ps1 b/publish.ps1
index 272355d..541fe28 100644
--- a/publish.ps1
+++ b/publish.ps1
@@ -18,7 +18,12 @@ dotnet publish "$root\src\PassKey.BrowserHost\PassKey.BrowserHost.csproj" `
-o "$root\$OutDir" --verbosity quiet
if ($LASTEXITCODE -ne 0) { throw "BrowserHost publish failed (exit $LASTEXITCODE)" }
-# 2. Publish Desktop (self-contained: bundles both WindowsAppSDK and .NET runtime)
+# 2. Publish Desktop (self-contained: .NET runtime is bundled in the output folder).
+# WindowsAppSDKSelfContained is NOT set, so Microsoft.UI.Xaml.dll and other
+# Windows App Runtime DLLs are NOT bundled — they are loaded at runtime from the
+# system-installed Windows App Runtime 1.8 via Bootstrap.Initialize().
+# This avoids both the STATUS_INVALID_IMAGE_HASH (NuGet DLLs rejected by HVCI)
+# and the .NET-not-found startup failure caused by a silent .NET installer failure.
Write-Host "`n[2/2] Publishing Desktop..." -ForegroundColor Yellow
$platformArg = if ($Arch -eq "arm64") { "ARM64" } else { "x64" }
dotnet publish "$root\src\PassKey.Desktop\PassKey.Desktop.csproj" `
diff --git a/src/PassKey.Desktop/PassKey.Desktop.csproj b/src/PassKey.Desktop/PassKey.Desktop.csproj
index fe907cb..b3b6821 100644
--- a/src/PassKey.Desktop/PassKey.Desktop.csproj
+++ b/src/PassKey.Desktop/PassKey.Desktop.csproj
@@ -14,9 +14,9 @@
None
false
PassKey.Desktop
- 1.0.9
- 1.0.9.0
- 1.0.9.0
+ 1.0.12
+ 1.0.12.0
+ 1.0.12.0
app.manifest
Assets\PassKey.ico
DISABLE_XAML_GENERATED_MAIN
@@ -28,7 +28,7 @@
-
+