Search code examples
c#cmdfontsregistry

Add fonts by CMD and C#


I write a method to install fonts by cmd and C#. My method as below :

void installFont(string fontsFolderPath, string fontName)
    {

        System.Diagnostics.Process process = new System.Diagnostics.Process();
        System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
        startInfo.FileName = "cmd.exe";
        String cc = @"/C  copy " + fontsFolderPath + @" C:\Windows\Fonts" + "&REG ADD HKLM\\Software\\Microsoft\\Windows_NT\\CurrentVersion\\Fonts /v " + fontName + @"  /t REG_SZ /d   " + fontName + @".ttf /f &pause"; ;
        startInfo.Arguments = cc;
        process.StartInfo = startInfo;
        process.Start();   
    }

but that is not add it, I try the cmd instructions individually, it's work correctly but when I request them by C# they are not working. I run VS as administrator. What the error in my code, or what the better way to do this Job. Thank you in advance.


Solution

  • As this question and answer in Microsoft site you can do that by copying te font file in Font folder and add that to registry as blow:

    File.Copy("BKoodakO.ttf", Path.Combine(GetFolderPath(SpecialFolder.Windows), "Fonts", "BKoodakO.ttf"),true);
    Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.LocalMachine.CreateSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts");
    key.SetValue("describtion for BKoodakO", "BKoodakO.ttf");
    key.Close();
    

    This code copy one file and if you have more file in a folder Get the font file in folder and then copy one by one. I test this way and it work fine. if you have question please comment answer. Note that the output must Run as administrator.

    Another way that use Windows dll to do that is:

            [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);
                }
            }