9

How can I install a font using C#?

I tried copying the fonts using File.Copy() but I am not allowed due to access rights limitations (UnauthorizedException).

What should I do?

bas
  • 13,550
  • 20
  • 69
  • 146
Shahin Rahbar
  • 196
  • 1
  • 1
  • 6
  • 2
    I'm pretty sure that installing new fonts involves more than just coping the files to the Fonts folder. – dtb Feb 10 '13 at 09:08
  • Does elevating privileges the application is running under solve the problem? – abatishchev Feb 10 '13 at 09:26
  • 1
    You should ask a different question: "How to install a font?". Your existing question has a trivial answer: Your user does not have access rights. This answer does not help you. – usr Feb 10 '13 at 09:28
  • @usr yes I agree too , just finished editing the question title, changes will reflect once edits are peer reviewed . – Baljeetsingh Sucharia Feb 10 '13 at 09:30

2 Answers2

18

You'll need a different approach installing fonts.

  • Use an installer (create a setup project) to install the fonts
  • Another (more easy) approach using a native method.

Declare the dll import:

    [DllImport("gdi32.dll", EntryPoint="AddFontResourceW", SetLastError=true)]
    public static extern int AddFontResource(
        [In][MarshalAs(UnmanagedType.LPWStr)]
        string lpFileName);

In your code:

    // Try install the font.
    result = AddFontResource(@"C:\MY_FONT_LOCATION\MY_NEW_FONT.TTF");
    error = Marshal.GetLastWin32Error();

The source:

http://www.brutaldev.com/post/2009/03/26/Installing-and-removing-fonts-using-C

I put it together in a unit test, I hope that helps:

[TestFixture]
public class Tests
{
    // Declaring a dll import is nothing more than copy/pasting the next method declaration in your code. 
    // You can call the method from your own code, that way you can call native 
    // methods, in this case, install a font into windows.
    [DllImport("gdi32.dll", EntryPoint = "AddFontResourceW", SetLastError = true)]
    public static extern int AddFontResource([In][MarshalAs(UnmanagedType.LPWStr)]
                                     string lpFileName);

    // This is a unit test sample, which just executes the native method and shows
    // you how to handle the result and get a potential error.
    [Test]
    public void InstallFont()
    {
        // Try install the font.
        var result = AddFontResource(@"C:\MY_FONT_LOCATION\MY_NEW_FONT.TTF");
        var error = Marshal.GetLastWin32Error();
        if (error != 0)
        {
            Console.WriteLine(new Win32Exception(error).Message);
        }
    }
}

That should help you on your way :)

bas
  • 13,550
  • 20
  • 69
  • 146
  • Can you explain more about "Declare the dll import:" bcuz i'm new to c# – Shahin Rahbar Feb 10 '13 at 09:43
  • @ShahinRahbar did you succeed yet? You didn't have to accept the answer upfront. Just upvote the answer if you are happy with it, accept the answer when your question is actually solved. Just let me know when you got it, if not, i'll try to help – bas Feb 10 '13 at 09:55
  • 1
    i dont have rep for upvote... it compile correctly but font doesnt install – Shahin Rahbar Feb 10 '13 at 10:14
  • The system cannot find the file Specified – Shahin Rahbar Feb 10 '13 at 10:26
  • Maybe this is the time to create a new question where you share the appropriate amount of information so that the SO community can help you. Copy/paste the code you have right now and share the error + stacktrace in a new question – bas Feb 10 '13 at 10:27
  • Can anyone help with the error: "Invalid menu handle" – Lee May 15 '15 at 16:10
  • @user2816736 Some context might help, and if you have a specific question, ask a new question iso comment on solved question – bas May 15 '15 at 17:05
  • Bravo! Bravissimo! By tests in this case. – S.H. Apr 12 '22 at 09:30
1
   internal static void InstalarFuente(string NombreFnt,string RutaFnt)
    {
        string CMD = string.Format("copy /Y \"{0}\" \"%WINDIR%\\Fonts\" ", RutaFnt);
        EjecutarCMD(CMD);

        System.IO.FileInfo FInfo = new System.IO.FileInfo(RutaFnt);
        CMD = string.Format("reg add \"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts\" /v \"{0}\" /t REG_SZ /d {1} /f", NombreFnt, FInfo.Name);
        EjecutarCMD(CMD);
    }

    public static void EjecutarCMD(string Comando)
    {
        System.Diagnostics.ProcessStartInfo Info = new System.Diagnostics.ProcessStartInfo("cmd.exe");
        Info.Arguments = string.Format("/c {0}", Comando);
        Info.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
        System.Diagnostics.Process.Start(Info);
    }