Repository navigation
Fix user mode fonts to install & add repair support - #6619
David Bennett (dkbennett) wants to merge 3 commits into
Conversation
This comment has been minimized.
This comment has been minimized.
Preserve font and pre-indexed source test hooks. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: a9e21d38-9ab1-4358-963d-9aadad897ad0
This comment has been minimized.
This comment has been minimized.
Add a regression for volatile shared test keys and acknowledge fontlayout in the spelling dictionary. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: a9e21d38-9ab1-4358-963d-9aadad897ad0
| fontContext.PackageId = ConvertToUTF16(installedPackage->GetProperty(Repository::PackageVersionProperty::Moniker)); | ||
| fontContext.PackageVersion = ConvertToUTF16(installedPackage->GetProperty(Repository::PackageVersionProperty::Version)); | ||
|
|
||
| if (fontContext.Scope == Manifest::ScopeEnum::User && Runtime::IsRunningWithNonDefaultFullToken()) |
There was a problem hiding this comment.
Whichever merges second will need to update this: #6634
Depending on the specifics, it might already be covered by the general repair flow blocker but I don't remember right now.
| context.Add<Execution::Data::RepairString>(repairCommand); | ||
| } | ||
|
|
||
| bool IsInstallerMappingRequired(Execution::Context& context) |
There was a problem hiding this comment.
I'm always the one saying we should have these semantic functions and then this one is not named well enough to indicate the semantic intention.
Can the comment at the call site be moved here?
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved font-path collisions and overly restrictive filename validation can block valid installs, repairs, and uninstalls, while malformed inventory mappings can truncate font listings.
3 open issues
What changed in this PR
This PR addresses user fonts disappearing after sign-out or restart by aligning their installation layout with machine-scope fonts. It also adds repair support using installed metadata, without downloading fonts.
Changes:
- Install user fonts directly in the shared Fonts directory with absolute-path discovery registrations.
- Add repair to migrate legacy nested installations and restore registrations.
- Update inventory, validation, uninstall, and tests for both layouts and filename collisions.
| File | Description |
|---|---|
| src/AppInstallerCommonCore/Public/winget/Fonts.h | Declares the font repair API. |
| src/AppInstallerCommonCore/Fonts.cpp | Implements flat installation, repair migration, mapping validation, and cleanup. |
| src/AppInstallerCLITests/TestHooks.h | Adds registry and session-isolation test hooks. |
| src/AppInstallerCLITests/RepairFlow.cpp | Tests font repair dispatch and elevation restrictions. |
| src/AppInstallerCLITests/Fonts.cpp | Covers layouts, collisions, migration, failures, and uninstall. |
| src/AppInstallerCLIE2ETests/Helpers/TestCommon.cs | Verifies exact inventory filenames and discovery registrations. |
| src/AppInstallerCLIE2ETests/FontCommand.cs | Updates installation checks and adds user-font repair coverage. |
| src/AppInstallerCLICore/Workflows/RepairFlow.cpp | Routes font packages through the repair workflow. |
| src/AppInstallerCLICore/Workflows/FontFlow.h | Declares the font repair workflow. |
| src/AppInstallerCLICore/Workflows/FontFlow.cpp | Repairs fonts from installed metadata with scope checks. |
| .github/actions/spelling/expect.txt | Adds the font-layout test tag to spelling expectations. |
Review effort: Balanced
| const bool inPackage = context.Scope == Manifest::ScopeEnum::User && | ||
| FontPathsEqual(path.parent_path(), GetUserFontPackagePath(context)); | ||
| THROW_HR_IF_MSG(APPINSTALLER_CLI_ERROR_FONT_VALIDATION_FAILED, | ||
| !path.is_absolute() || !Manifest::IsValueSafeForPathConstruction(path.filename().u8string()) || (!inRoot && !inPackage), |
| for (const auto& fontFileInfo : validationResult.FontFileInfos) | ||
| { |
| context.PackageId = packageId; | ||
| context.PackageVersion = version; | ||
| auto fontFile = CreateFontFileInfo(context, filePath, ConvertToUTF16(versionValue.Name())); | ||
| auto fontFile = CreateFontFileInfo(context, filePath); |

📖 Description
Align user-scope font installation with the machine-scope model to address fonts missing from Windows discovery after sign-out or restart.
%LOCALAPPDATA%\Microsoft\Windows\Fontsand register their absolute paths underHKCU\Software\Microsoft\Windows NT\CurrentVersion\Fonts.Machine-scope discovery registrations retain their relative filename values. Migration rollback is per-file and best effort.
🔗 References
Addresses #6535.
🔍 Validation
Automated coverage checks exact inventory filenames, flat installation paths, REG_SZ discovery values, scope isolation, filename collisions, repair migration, failure handling, and uninstall cleanup.
AppInstallerCLITests.exe '[fonts],[FontHelper],[RepairFlow]'
Passed: 334 assertions in 29 test cases.
wingetdev font list --details --disable-interactivity: passed against the locally deployed dev build with fonts enabled.✅ Checklist
🤖 AI Assistance
📋 Issue Type
Microsoft Reviewers: Open in CodeFlow