-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Font Install #5042
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Font Install #5042
Changes from 13 commits
aae3caa
42e53bf
4efa09f
aeab647
e73e8af
8678d12
745a4ed
b5f3c16
bc8221f
8f7a47d
fa1c995
9550aed
d21f3ee
1491913
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,98 @@ | ||
| // Copyright (c) Microsoft Corporation. | ||
| // Licensed under the MIT License. | ||
| #include "pch.h" | ||
| #include "ExecutionContext.h" | ||
| #include "FontInstaller.h" | ||
| #include <winget/Fonts.h> | ||
| #include <winget/Manifest.h> | ||
| #include <winget/ManifestCommon.h> | ||
| #include <winget/Filesystem.h> | ||
| #include <AppInstallerErrors.h> | ||
| #include <AppInstallerRuntime.h> | ||
|
|
||
| namespace AppInstaller::CLI::Font | ||
| { | ||
| namespace | ||
| { | ||
| constexpr std::wstring_view s_FontsPathSubkey = L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts"; | ||
| constexpr std::wstring_view s_TrueType = L" (TrueType)"; | ||
|
|
||
| bool IsTrueTypeFont(DWRITE_FONT_FILE_TYPE fileType) | ||
| { | ||
| return ( | ||
| fileType == DWRITE_FONT_FILE_TYPE_TRUETYPE || | ||
| fileType == DWRITE_FONT_FILE_TYPE_TRUETYPE_COLLECTION | ||
| ); | ||
| } | ||
| } | ||
|
|
||
| FontInstaller::FontInstaller(Manifest::ScopeEnum scope) : m_scope(scope) | ||
| { | ||
| if (scope == Manifest::ScopeEnum::Machine) | ||
| { | ||
| m_installLocation = Runtime::GetPathTo(Runtime::PathName::FontsMachineInstallLocation); | ||
| m_key = Registry::Key::Create(HKEY_LOCAL_MACHINE, std::wstring{ s_FontsPathSubkey }); | ||
| } | ||
| else | ||
| { | ||
| m_installLocation = Runtime::GetPathTo(Runtime::PathName::FontsUserInstallLocation); | ||
| m_key = Registry::Key::Create(HKEY_CURRENT_USER, std::wstring{ s_FontsPathSubkey }); | ||
| } | ||
| } | ||
|
|
||
| void FontInstaller::Install(const std::vector<FontFile>& fontFiles) | ||
| { | ||
| for (const auto& fontFile : fontFiles) | ||
| { | ||
| const auto& filePath = fontFile.FilePath; | ||
| const auto& fileName = filePath.filename(); | ||
| const auto& destinationPath = m_installLocation / fileName; | ||
|
|
||
| AICLI_LOG(CLI, Verbose, << "Getting Font title"); | ||
|
|
||
| std::wstring title = AppInstaller::Fonts::GetFontFileTitle(filePath); | ||
|
|
||
| if (IsTrueTypeFont(fontFile.FileType)) | ||
| { | ||
| title += s_TrueType; | ||
JohnMcPMS marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| // If font subkey already exists, remove the font file if it exists. | ||
ryfu-msft marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| if (m_key[title].has_value()) | ||
| { | ||
| AICLI_LOG(CLI, Info, << "Existing font subkey found:" << AppInstaller::Utility::ConvertToUTF8(title)); | ||
| std::filesystem::path existingFontFilePath = { m_key[title]->GetValue<Registry::Value::Type::String>() }; | ||
|
|
||
| if (m_scope == Manifest::ScopeEnum::Machine) | ||
| { | ||
| // Font entries in the HKEY_LOCAL_MACHINE hive only have the filename specified as the value. Prepend install location. | ||
| existingFontFilePath = m_installLocation / existingFontFilePath; | ||
| } | ||
|
|
||
| if (std::filesystem::exists(existingFontFilePath)) | ||
| { | ||
| AICLI_LOG(CLI, Info, << "Removing existing font file at:" << existingFontFilePath); | ||
| std::filesystem::remove(existingFontFilePath); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the operation fails, we cannot revert this. Much like my comment on the rest of the operation being reverted on failure, we want some mechanism to put things back the way they were. I would think that to make it maximally recoverable, one would need to:
But I don't think we need to be that extreme (handling full on process termination). A more modest approach would have a vector of |
||
| } | ||
| } | ||
|
|
||
| AICLI_LOG(CLI, Info, << "Creating font subkey with name: " << AppInstaller::Utility::ConvertToUTF8(title)); | ||
| if (m_scope == Manifest::ScopeEnum::Machine) | ||
| { | ||
| m_key.SetValue(title, fileName, REG_SZ); | ||
|
||
| } | ||
| else | ||
| { | ||
| m_key.SetValue(title, destinationPath, REG_SZ); | ||
JohnMcPMS marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| AICLI_LOG(CLI, Info, << "Moving font file to: " << destinationPath); | ||
| AppInstaller::Filesystem::RenameFile(filePath, destinationPath); | ||
|
||
| } | ||
| } | ||
|
|
||
| void FontInstaller::Uninstall(const std::wstring& familyName) | ||
| { | ||
| UNREFERENCED_PARAMETER(familyName); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| // Copyright (c) Microsoft Corporation. | ||
| // Licensed under the MIT License. | ||
| #pragma once | ||
| #include <filesystem> | ||
| #include <winget/Fonts.h> | ||
|
|
||
| namespace AppInstaller::CLI::Font | ||
| { | ||
| struct FontFile | ||
| { | ||
| FontFile(std::filesystem::path filePath, DWRITE_FONT_FILE_TYPE fileType) | ||
| : FilePath(std::move(filePath)), FileType(fileType) {} | ||
|
|
||
| std::filesystem::path FilePath; | ||
| DWRITE_FONT_FILE_TYPE FileType; | ||
| }; | ||
|
|
||
| struct FontInstaller | ||
| { | ||
| FontInstaller(Manifest::ScopeEnum scope); | ||
|
|
||
| std::filesystem::path FontFileLocation; | ||
|
|
||
| void Install(const std::vector<FontFile>& fontFiles); | ||
|
|
||
| void Uninstall(const std::wstring& familyName); | ||
|
|
||
| private: | ||
| Manifest::ScopeEnum m_scope; | ||
| std::filesystem::path m_installLocation; | ||
| Registry::Key m_key; | ||
| }; | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.