温馨提示:本文翻译自stackoverflow.com,查看原文请点击:.net - How to remove a font from Windows in C#?
.net .net-core c# fonts windows

.net - 如何从Windows中使用C#删除字体?

发布于 2020-03-29 21:45:55

我正在努力使这种方法起作用。

using Microsoft.Win32;
using System;
using System.Drawing;
using System.Drawing.Text;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;

public static class FontManager
{
    [DllImport("user32.dll")]
    public static extern int SendMessage(int hWnd, uint Msg, int wParam, int lParam);
    [DllImport("gdi32.dll", EntryPoint = "RemoveFontResourceW", SetLastError = true)]
    public static extern int RemoveFontResource([In][MarshalAs(UnmanagedType.LPWStr)] string lpFileName);

    /// <summary>
    /// Uninstall a font from the system.
    /// </summary>
    /// <param name="fontFile">The absolute path of the font.</param>
    public static void Uninstall(string fontFile)
    {
        var targetFontFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Fonts), Path.GetFileName(fontFile));

        if (File.Exists(targetFontFile))
        {
            // Get the font name.
            PrivateFontCollection fontCollection = new PrivateFontCollection();
            fontCollection.AddFontFile(targetFontFile);
            var actualFontName = fontCollection.Families[0].Name;

            // Remove the font from the registry.
            var key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts", writable: true);

            if (key.GetValueNames().Contains(actualFontName))
            {
                key.DeleteValue(actualFontName);
            }

            key.Close();

            // Remove the font from the system.
            RemoveFontResource(targetFontFile);

            // Remove the font file from the fonts directory.
            File.SetAttributes(targetFontFile, FileAttributes.Normal);
            File.Delete(targetFontFile);

            // Broadcast a message that the fonts has changed.
            const int WM_FONTCHANGE = 0x001D;
            const int HWND_BROADCAST = 0xffff;
            SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);
        }
    }
}

但是我无法从Fonts目录中删除字体。

// Remove the font file from the fonts directory.
File.SetAttributes(targetFontFile, FileAttributes.Normal);
File.Delete(targetFontFile);

我得到这个例外:

System.UnauthorizedAccessException: 'Access to the path 'C:\Windows\Fonts\JetBrainsMono-Bold.ttf' is denied.'

字体已正确从注册表中卸载/注销。

是否有解决方法,可以从此目录中删除/清除已卸载/未注册的字体?

查看更多

提问者
0lan
被浏览
125
0lan 2020-02-04 23:08

Windows将无法物理删除的字体移动到Deleted隐藏目录中。

这是与C#相同的代码。

// Try to delete the font file physically.
try
{
    File.Delete(targetFontFile);
}
// Sometimes it's impossible to delete the font because it's in use by another process.
catch (Exception)
{
    // Create the hidden Deleted directory if it doesn't exist.
    var deletedDirectory = Path.Combine(Path.GetDirectoryName(targetFontFile), "Deleted");
    if (!Directory.Exists(deletedDirectory))
    {
        DirectoryInfo di = Directory.CreateDirectory(deletedDirectory);
        di.Attributes = FileAttributes.Directory | FileAttributes.Hidden;
    }

    // Move the font file into the Deleted directory.
    File.Move(targetFontFile, Path.Combine(deletedDirectory, Path.GetFileName(targetFontFile).ToUpper()));
}

Windows 10将字体文件重命名为大写,因此我的代码也是如此。