Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to install a Font programmatically (C#)

is there a way to permanently add a Font to a Windows 7/8 PC programmatically? I have read several posts about the AddFontResource DLL-Import, but it doesn't seem to work.

Besides of that, the MSDN Documentation says the font will be deleted after a restart of the computer, unless the font is added into the registry.

How can I install a font permanently? How can I add the font to the registry? Is it always the same name/entry?

I have to add the font dynamically on runtime, because I get the font as soon as the user selects it.

Remark: I know how to add a registry entry. My question is more about the compatibility between Windows XP, Vista, 7 and 8 and the different font-types. Maybe there is a way to start an other exe which installs the font for me.

like image 910
El Mac Avatar asked Feb 24 '14 11:02

El Mac


People also ask

How do I add fonts to C drive?

To activate a font on any version of Windows, navigate to Computer ▸ Local Disk (C:) ▸ Windows ▸ Fonts. Locate the folder you've expanded from the downloaded . zip file, and drag the font files into the Fonts folder.

How do I manually install a font?

Right-click the fonts you want, and click Install. If you're prompted to allow the program to make changes to your computer, and if you trust the source of the font, click Yes. Your new fonts will appear in the fonts list in Word.

How do I install a TTF font?

To install the TrueType font in Windows:Click on Start, Select, Settings and click on Control Panel. Click on Fonts, click on File in the main tool bar and select Install New Font. Select the folder where the font is located. The fonts will appear; select the desired font that is titled TrueType and click on OK.

How do I add a font to a package?

Double-click on “My Computer.” Then double-click on the “Control Panels” icon, and then the “Fonts” icon. In the Fonts window, select the File menu, and choose “Install New Font.” Navigate to the folder that contains the fonts you want to install.


3 Answers

As you mentioned, you can launch other executables to install TrueType Fonts for you. I don't know your specific use cases but I'll run down the methods I know of and maybe one will be of use to you.

Windows has a built-in utility called fontview.exe, which you can invoke simply by calling Process.Start("Path\to\file.ttf") on any valid TrueType Font... assuming default file associations. This is akin to launching it manually from Windows Explorer. The advantage here is it's really trivial, but it still requires user interaction per font to install. As far as I know there is no way to invoke the "Install" portion of this process as an argument, but even if there was you'd still have to elevate permissions and battle UAC.

The more intriguing option is a utility called FontReg that replaces the deprecated fontinst.exe that was included on older versions of Windows. FontReg enables you to programatically install an entire directory of Fonts by invoking the executable with the /copy switch:

    var info = new ProcessStartInfo()         {             FileName = "Path\to\FontReg.exe",             Arguments = "/copy",             UseShellExecute = false,             WindowStyle = ProcessWindowStyle.Hidden          };     Process.Start(info); 

Note that the Fonts have to be in the root of wherever FontReg.exe is located. You'll also have to have administrator privileges. If you need your Font installations to be completely transparent, I would suggest launching your application with elevated permissions and approve of the UAC up front, that way when you spawn your child processes you wont need user approval Permissions stuff

like image 160
B L Avatar answered Oct 11 '22 21:10

B L


I've been having the same issue for the past few days and each solution I found was producing different problems.

I managed to come up with a working code with my colleague and I thought I'd share it for everyone. The code can be found in the following pastebin link:

Installing a font programatically in C#

EDIT In the event this code becomes irretrievable in the future, I have copied it directly into the answer.

[DllImport("gdi32", EntryPoint = "AddFontResource")]
public static extern int AddFontResourceA(string lpFileName);
[System.Runtime.InteropServices.DllImport("gdi32.dll")]
private static extern int AddFontResource(string lpszFilename);
[System.Runtime.InteropServices.DllImport("gdi32.dll")]
private static extern int CreateScalableFontResource(uint fdwHidden, string
    lpszFontRes, string lpszFontFile, string lpszCurrentPath);

/// <summary>
/// Installs font on the user's system and adds it to the registry so it's available on the next session
/// Your font must be included in your project with its build path set to 'Content' and its Copy property
/// set to 'Copy Always'
/// </summary>
/// <param name="contentFontName">Your font to be passed as a resource (i.e. "myfont.tff")</param>
private static void RegisterFont(string contentFontName)
{
    // Creates the full path where your font will be installed
    var fontDestination = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Fonts), contentFontName);

    if (!File.Exists(fontDestination))
    {
        // Copies font to destination
        System.IO.File.Copy(Path.Combine(System.IO.Directory.GetCurrentDirectory(), contentFontName), fontDestination);

        // Retrieves font name
        // Makes sure you reference System.Drawing
        PrivateFontCollection fontCol = new PrivateFontCollection();
        fontCol.AddFontFile(fontDestination);
        var actualFontName = fontCol.Families[0].Name;

        //Add font
        AddFontResource(fontDestination);
        //Add registry entry   
        Registry.SetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts",actualFontName, contentFontName, RegistryValueKind.String);
    }
}
like image 32
kkyr Avatar answered Oct 11 '22 21:10

kkyr


According to docs of AddFontResource()

This function installs the font only for the current session. When the system restarts, the font will not be present. To have the font installed even after restarting the system, the font must be listed in the registry.

So the best option i found is to copy the font to windows font directory

File.Copy("MyNewFont.ttf",
    Path.Combine(Environment.GetFolderPath(SpecialFolder.Windows),
        "Fonts", "MyNewFont.ttf"));

And then add respective entries in registery,Like

Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.LocalMachine.CreateSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts");
                    key.SetValue("My Font Description", "fontname.tff");
                    key.Close();
like image 29
Zain Ali Avatar answered Oct 11 '22 21:10

Zain Ali