2

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.

Ali A. Jalil
  • 873
  • 11
  • 25
  • This could be a big maybe but you have "C:\windows\Fonts" + "&REG" there is no space between your fonts path and your registry command. Its possible CMD is interpreting that as one continuous path. Also I am not sure you can run all those as 1 argument you might have to redirect the input and write the commands individually. here is a link on how to do that https://stackoverflow.com/questions/437419/execute-multiple-command-lines-with-the-same-process-using-net – Bearcat9425 Jul 24 '17 at 14:22
  • I add space but it's not working. – Ali A. Jalil Jul 24 '17 at 14:26
  • then its likely that copy is interpreting your reg commands as switches for it and not understanding what to do. Have a look at the link I posted and specifically the one that shows how to redirect the input so that you can run multiple commands like they are new commands to that same process. – Bearcat9425 Jul 24 '17 at 14:30
  • Can you show exactly what the cc string is when you start the process. – PaulF Jul 24 '17 at 14:31
  • @PaulF that is cc: /C copy C:\Folder\ C:\Windows\Fonts &REG ADD HKLM\Software\Microsoft\Windows_NT\CurrentVersion\Fonts /v Libertinage /t REG_SZ /d Libertinage.ttf /f &pause – Ali A. Jalil Jul 24 '17 at 14:37
  • why you dont use simple copy and then add to registry..i test this way and it work fine..if you want i can put some code to your hint – Ali Jul 24 '17 at 14:38
  • @combo_ci can you do that please? – Ali A. Jalil Jul 24 '17 at 14:39
  • @PaulF What can I do to run the cmd? – Ali A. Jalil Jul 24 '17 at 15:42
  • I can't see anything obviously wrong - see the last comment in the answer below about running as administrator – PaulF Jul 24 '17 at 15:45

1 Answers1

1

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);
            }
        }
Ali
  • 3,373
  • 5
  • 42
  • 54
  • I try the first method, it's work, but : 1-when the folder is in c directory it can't copy it. 2- If I not run the program as administrator it's also not work. Many Thanks. – Ali A. Jalil Jul 24 '17 at 15:30
  • if you run visual studio as administrator, you not need to run it as administrator, do you try it? – Ali Jul 24 '17 at 15:32
  • I not need when I release my project to force user to run it as administrator, How can I do that. And about folder in c, there is no error but when I check to font existence, it's not exist; i.e. it's cant copy font from folder c. – Ali A. Jalil Jul 24 '17 at 15:39
  • about Run as administrator please see [this question](https://stackoverflow.com/questions/2818179/how-do-i-force-my-net-application-to-run-as-administrator) – Ali Jul 24 '17 at 15:44
  • Ali, When a code work, if you have a special case that it not work, you must looking for the reason of that case in your computer, maybe a special permition on your C:/ dive, or some software pervent to do that, if you put in a folder in c:/ , the program is work fine? – Ali Jul 24 '17 at 15:49