I'm on the way to getting this method to work.
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);
}
}
}
However I can't delete the font from the Fonts directory.
// Remove the font file from the fonts directory.
File.SetAttributes(targetFontFile, FileAttributes.Normal);
File.Delete(targetFontFile);
I get this exception:
System.UnauthorizedAccessException: 'Access to the path 'C:\Windows\Fonts\JetBrainsMono-Bold.ttf' is denied.'
The font is properly uninstalled/unregistered from the Registry.
Is there maybe a workaround to remove/clear the uninstalled/unregistered fonts from this directory?
Windows moves fonts it can't physically remove into a Deleted
hidden directory.
Here's the code to do the same with 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 renames the font file to upper case, so my code does the same.