KEMBAR78
Font Install, Uninstall, additional Font List by dkbennett · Pull Request #5566 · microsoft/winget-cli · GitHub
Skip to content

Conversation

dkbennett
Copy link
Member

@dkbennett dkbennett commented Jun 30, 2025

Implements a good chunk of #166 Key features and changes:

All of the below are experimental behind the fonts experimental feature. Font install is implemented as a winget-common installer that models most of the font install behavior of the operating system in its key components. It deviates from a normal font install in that the install locations and registry key paths are a little different in order to map fonts to an identifiable version-specific deterministic location. This is so we may more easily identify font packages and remove them and avoid font collisions, torn state, or removing fonts from other packages.

Font List update

  • Added new font list "--files" option that lists fonts by installed files and their known validity state
    • Fonts are listed by file where they are located and have an assigned identifier for later use in removal.
    • The Font Status reflects whether the registry matches an actual font file on disk (fonts without a file are labeled "Corrupt").
    • The intent here is to add filters later to get a better idea of what fonts are on the system, where they came from, and which might need repair or removal. At present my system had over 300 font files installed so the list is quite large.

Font Install

  • Add font support for install. This is the base WinGet install command, not the 'font' sub-command.
  • Requires font experimental feature to be enabled.
  • Added the core Font evaluation code to AppInstallerCommonCore so it is not strictly bound to the CLI.
  • The font install scheme puts WinGet installed font packages in sub folders and subkeys where they can exist side-by-side with other font packages without worry of file collision and easier high-confidence removal/upgrade and rollback.
  • Registers the font with the current session and notifies other apps of the new font availability.
  • Configures the font to be loaded on subsequent sessions.
  • Install works for machine and user fonts.

*Font Uninstall

  • Added font support for uninstall. This is the base WinGet uninstall command, not the 'font' sub-command.
  • Requires font Experimental feature to be enabled.
  • Uninstall works for WinGet-installed fonts only at this time.

** Font List*

  • Added font package detection to the PredefinedInstalledSource.
  • This allows font packages to be detected for uninstall.

Workflows

  • Support for Font Install and Uninstall

Tested

  • Added many unit tests which exercise the the Font install, uninstall, information gathering, listing, for machine and user scopes. All of the new core code added is exercised in unit tests.
  • All scopes for install using unit tests and local web server.
  • Install and uninstall with manifest an local server.
  • Install and uninstall and list with package from a private package source.
  • Verified ACLs on the folders match expected permissions for visibility.
  • Verified per-user and per-machine fonts are installed correctly and show up in Font Settings immediately.

NOT part of this PR and is likely a future PR

  • Font upgrade (a new version will be installed side-by-side)

  • Uninstall of non-packaged fonts. This is in plan, just not in the scope of this PR.

  • I have signed the Contributor License Agreement.

  • I have updated the Release Notes.

  • This pull request is related to an issue.


Microsoft Reviewers: Open in CodeFlow

@dkbennett dkbennett requested review from JohnMcPMS and yao-msft June 30, 2025 06:13
@github-actions

This comment has been minimized.

Fix copypasta error

Co-authored-by: Muhammad Danish <mdanishkhdev@gmail.com>
@github-actions

This comment has been minimized.

Fix argument string consistency

Co-authored-by: Muhammad Danish <mdanishkhdev@gmail.com>
@github-actions

This comment has been minimized.

dkbennett and others added 2 commits June 30, 2025 11:03
comment typo

Co-authored-by: Kaleb Luedtke <trenlymc@gmail.com>
comment typo

Co-authored-by: Kaleb Luedtke <trenlymc@gmail.com>
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@dkbennett dkbennett requested a review from JohnMcPMS September 20, 2025 20:25
Copy link
Member

@JohnMcPMS JohnMcPMS left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is still experimental, so it can be the way it is for now, but I don't think enough design thought has gone into how fonts fit into the ecosystem of existing commands / COM. We should be able to manage (enumerate and uninstall) fonts outside of those that have been installed by us. COM callers should be able to as well.

Fonts going into the main installed packages catalog is tricky, mostly because I don't think people want list to show every single font. But maybe that isn't a big deal. I think that I would make these changes to support that and things built upon it (all of these are toward the goal of supporting fonts, but not all are required as part of "fonts deliverable"):

  1. Convert PredefinedInstalledSourceFactory::Filter to be a set of flags that indicate what to include / behaviors. It would be something like { User, Machine, ARP, MSIX, Fonts, UpdateCache, None=0, All=(-1) }. This is mostly about making the logic easier than it is now.
  2. Consider adding these flags to COM and / or list command to make filtering easier and faster.
  3. Add all fonts to the installed source, with enough identification and meaning to values to make them usable.
  4. Add a show like command / option to list to get additional information for installed items. That can go down different paths depending on the installed item type. font list could be removed and folded into that.

@dkbennett dkbennett requested a review from JohnMcPMS September 29, 2025 17:30

void RemoveAllFontResources(std::filesystem::path filePath)
{
// The recommended uninstall method of a font is to call RemoveFontResource until it fails,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bumping this again.

fileInfo.PackageVersion = context.PackageVersion;
fileInfo.InstallerSource = context.InstallerSource;
fileInfo.Scope = context.Scope;
if (title.has_value())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bump.

@dkbennett dkbennett requested a review from JohnMcPMS October 1, 2025 19:27
@github-actions

This comment has been minimized.

@dkbennett
Copy link
Member Author

Since i can't reply to the comment about AddFontResource or RemoveFontResource, I will update on that here.

I did some extensive testing and investigation of using and not using AddFontResource and RemoveFontResource. Using it was the guidance of font experts but the documentation on learn seems a little off. I verified using Notepad++ and Office Word that these two things need to be used as the code uses them or the Font Resources are not properly added or removed to the current session and the apps cannot detect the new font being available without it. They are used in this code as it was recommended that I use it and is consistent with internal font install behavior.

So these methods add and remove the font internally to the current active session and allows apps to use the fonts and detect them immediately. It is not tied to the current app; adding the font resource makes it available to all apps, and removing it removes it from all apps. I did not encounter issues of files-in-use when removing fonts the apps were actively using, this appears to be handled gracefully.

Moreover, removing a font while it is being used is handled well by the apps. Word was particularly graceful - adding a font was immediately available to the running app, you could use it, then when the font is removed via WinGet the document updated the text using that font to a similiar font. After re-adding the font via WinGet, Word updated the text back to the desired font.

@dkbennett dkbennett merged commit 329b197 into microsoft:master Oct 2, 2025
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants