Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ Installer/Output/
*.iss.bak
*.exe.sig

# Windows App Runtime redistributable — exceeds GitHub's 100 MB limit.
# Download before building the installer:
# .\Installer\Download-Runtime.ps1
Installer/WindowsAppRuntimeInstall-x64.exe

# ─── MSIX / AppPackages ───────────────────────────────────────────────────────
AppPackages/

Expand Down
23 changes: 22 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [1.0.9] - 2026-05-04

### Fixed
- **HVCI crash (STATUS_INVALID_IMAGE_HASH)**: PassKey v1.0.7 and v1.0.8 crashed silently on
every PC with Hypervisor-Protected Code Integrity (HVCI) enabled — the majority of modern
Windows 11 systems with TPM. Windows Code Integrity rejected the NuGet-bundled
`Microsoft.UI.Xaml.dll` with exception code `0xc000027b` because NuGet copies are not
registered in the Windows system catalog. No window ever appeared and no crash log was
written (the exception is a native SEH fault that bypasses .NET `catch`).

The fix removes `WindowsAppSDKSelfContained` from the build (the publish folder no longer
contains `Microsoft.UI.Xaml.dll`), adds an explicit `Bootstrap.Initialize(1.8)` call in
`Program.cs`, and bundles the official **Windows App Runtime 1.8** installer
(`WindowsAppRuntimeInstall-x64.exe`) inside the PassKey installer. The runtime is installed
silently during setup; its DLLs are fully trusted by Windows Code Integrity.

A user-visible error dialog (Win32 `MessageBoxW`) is shown on the rare occasion that
`Bootstrap.Initialize` fails (e.g. corrupt runtime installation), replacing the previous
silent disappearance.

## [1.0.8] - 2026-05-04

### Fixed
Expand Down Expand Up @@ -128,7 +148,8 @@ 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.8...HEAD
[Unreleased]: https://github.com/pexatar/PassKey/compare/v1.0.9...HEAD
[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
[1.0.6]: https://github.com/pexatar/PassKey/compare/v1.0.5...v1.0.6
Expand Down
19 changes: 19 additions & 0 deletions Installer/Download-Runtime.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# 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).
#
# 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"

if (Test-Path $output) {
Write-Host "Already present: $output" -ForegroundColor Green
exit 0
}

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
17 changes: 15 additions & 2 deletions Installer/PassKey.iss
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
[Setup]
AppId={{A7F3C2D1-8E4B-4F9A-B6D5-3C1E7A2F0D84}
AppName=PassKey
AppVersion=1.0.8
AppVerName=PassKey 1.0.8
AppVersion=1.0.9
AppVerName=PassKey 1.0.9
AppPublisher=Giuseppe Imperato
AppPublisherURL=https://github.com/pexatar/PassKey
AppSupportURL=https://github.com/pexatar/PassKey/issues
Expand Down Expand Up @@ -38,6 +38,12 @@ Name: "portuguese"; MessagesFile: "compiler:Languages\Portuguese.isl"
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.
Source: "WindowsAppRuntimeInstall-x64.exe"; DestDir: "{tmp}"; Flags: ignoreversion deleteafterinstall

; Published self-contained output (Desktop + BrowserHost)
Source: "..\publish\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs

Expand All @@ -59,4 +65,11 @@ Root: HKCU; Subkey: "SOFTWARE\Google\Chrome\NativeMessagingHosts\com.passkey.hos
Root: HKCU; Subkey: "SOFTWARE\Mozilla\NativeMessagingHosts\com.passkey.host"; ValueType: string; ValueData: "{app}\com.passkey.host.json"; Flags: uninsdeletevalue

[Run]
; 1. Install Windows App Runtime 1.8 silently (waits for completion before continuing).
; RunOnceId prevents re-running on reinstall/repair if the runtime is already present.
Filename: "{tmp}\WindowsAppRuntimeInstall-x64.exe"; Parameters: "--quiet"; \
StatusMsg: "Installing Windows App Runtime 1.8..."; \
Flags: waituntilterminated; RunOnceId: "WinAppRuntime18"

; 2. Launch PassKey after installation completes.
Filename: "{app}\PassKey.Desktop.exe"; Description: "Launch PassKey"; Flags: nowait postinstall skipifsilent
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ PassKey stores your passwords, credit cards, identities, and secure notes in a l

| Version | Platform | Type |
|---------|----------|------|
| [v1.0.8](https://github.com/pexatar/PassKey/releases/tag/v1.0.8) | Windows x64 | Installer EXE |
| [v1.0.8](https://github.com/pexatar/PassKey/releases/tag/v1.0.8) | Windows x64 | Portable ZIP |
| [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 |

> **Requirements:** Windows 10 version 1809 (build 17763) or later, x64 processor.
> No .NET runtime required — PassKey is fully self-contained.
Expand Down
7 changes: 3 additions & 4 deletions src/PassKey.Desktop/PassKey.Desktop.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,11 @@
<UseWinUI>true</UseWinUI>
<EnableMsixTooling>true</EnableMsixTooling>
<WindowsPackageType>None</WindowsPackageType>
<WindowsAppSDKSelfContained>true</WindowsAppSDKSelfContained>
<PublishAot>false</PublishAot>
<RootNamespace>PassKey.Desktop</RootNamespace>
<Version>1.0.8</Version>
<AssemblyVersion>1.0.8.0</AssemblyVersion>
<FileVersion>1.0.8.0</FileVersion>
<Version>1.0.9</Version>
<AssemblyVersion>1.0.9.0</AssemblyVersion>
<FileVersion>1.0.9.0</FileVersion>
<ApplicationManifest>app.manifest</ApplicationManifest>
<ApplicationIcon>Assets\PassKey.ico</ApplicationIcon>
<DefineConstants>DISABLE_XAML_GENERATED_MAIN</DefineConstants>
Expand Down
29 changes: 29 additions & 0 deletions src/PassKey.Desktop/Program.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Reflection;
using System.Runtime.InteropServices;
using Microsoft.UI.Dispatching;
using Microsoft.UI.Xaml;

Expand Down Expand Up @@ -61,6 +62,31 @@ public static void Main(string[] args)
// ── App startup ──────────────────────────────────────────────────────
// Note: ApplySavedLanguage() is called inside App() constructor before
// InitializeComponent(), following the official Microsoft docs pattern.

// ── Windows App Runtime bootstrap ────────────────────────────────────
// Required for unpackaged apps with a custom Main (DISABLE_XAML_GENERATED_MAIN)
// when WindowsAppSDKSelfContained is NOT set. Locates and activates the
// system-installed Windows App Runtime 1.8 instead of NuGet-bundled copies.
// NuGet-bundled Microsoft.UI.Xaml.dll triggers STATUS_INVALID_IMAGE_HASH
// (0xc000027b) on HVCI-enabled systems because it is not in the Windows
// Code Integrity system catalog.
try
{
// 0x00010008 = (1 << 16) | 8 → minimum version 1.8
Microsoft.Windows.ApplicationModel.DynamicDependency.Bootstrap.Initialize(0x00010008);
}
catch (Exception ex)
{
WriteCrashLog(ex);
_ = MessageBoxW(
IntPtr.Zero,
"Windows App Runtime 1.8 is required but could not be initialised.\n\n" +
"Please reinstall PassKey to restore the required runtime.",
"PassKey — Missing Runtime",
0x10 /* MB_ICONERROR */);
return;
}

try
{
WinRT.ComWrappersSupport.InitializeComWrappers();
Expand Down Expand Up @@ -118,4 +144,7 @@ private static void WriteCrashLog(Exception ex)
// If we can't write the log, there is nothing more we can do.
}
}

[DllImport("user32.dll", CharSet = CharSet.Unicode)]
private static extern int MessageBoxW(IntPtr hWnd, string text, string caption, uint type);
}
Loading