728x90
반응형
SMALL
C#으로 프로그램을 만들 때 Font를 Custom Font를 사용하면,
사용자 PC에 Custom Font가 없는 경우가 있을 수 있다.
이런 경우는 Font는 기본 Font가 적용되어, Custom Font를 사용한 의미가 없어진다.
이를 위해서는 사용자가 프로그램을 실행할 때, 자동으로 Custom Font를 설치가 되어야 한다.
그럼 Custom Font를 자동으로 설치하는 로직을 알아보도록 하자.

 

■ Font를 자동으로 설치하는 방법

1. 제일 먼저 실행되는 프로젝트 파일에 로직을 넣는다.

  - 예) FontProject라는 프로젝트 Program.cs 파일에 로직을 넣는다.

  - 초기화면은 아래와 같다. (다 똑같지는 않음)

# Program.cs

namespace FontProject

{

     internal static class Program

     {

           /// <summary>

           ///   The main entry point for the application.

           /// </summary>

           [STAThread]

           static void Main()

           {

                 // To customize application configuration such as set high DPI settings or default font,

                 // see https://aka.ms/applicationconfiguration.

                 ApplicationConfiguration.Initialize();

 

                 // Custom Font를 설치한다. 경로는 Custom Font 파일이 있는 모아둔 폴더로 지정             

                 // 이 부분은 추가해야 한다!

                 CustomFontInstall.InstallFontsFromFolder(@"C:\Font");                 

 

                 Application.Run(new Form1());

           }

     }

}

 

2. Program.cs에서는 호출만 할 것이기 때문에, Font와 관련된 Class파일을 만든다.

# CustomFontInstall.cs

using Microsoft.Win32;

using System.Drawing.Text;

using System.Runtime.InteropServices;

 

namespace FontProject

{

     public static class CustomFontInstall

     {

           [DllImport("gdi32.dll")]

           private static extern int AddFontResource(string lpFilename);

 

           [DllImport("user32.dll")]

           private static extern bool SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);

 

           private const int WM_FONTCHANGE = 0x001D;

 

           public static void InstallFontsFromFolder(string pSourceFolder)

           {

                string sFontPath = @"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts";

                string sFontsFolder = Environment.GetFolderPath(Environment.SpecialFolder.Fonts);

 

                // Windows에서 Font 설치 정보를 관리하는 레지스트리 경로

                RegistryKey regFontRegKey = Registry.LocalMachine.OpenSubKey(sFontPath, false);

 

                foreach (string file in Directory.GetFiles(pSourceFolder, "*.ttf"))

                {

                     string sFontFileName = Path.GetFileName(file);

                     string sFontDestPath = Path.Combine(sFontsFolder, sFontFileName);

                     string sFontDisplayName = GetFontDisplayName(file);

 

                     // 파일 Font이름은 같을 수 있기 때문에, 내부 Font이름을 가져온다. - Font설치 Skip방지를 위해서 자세하게 비교

                     string sFontStyleName = Path.GetFileNameWithoutExtension(file);                

 

                     if (string.IsNullOrWhiteSpace(sFontDisplayName))

                     {

                          // 폰트이름을 가지고 올 수 없음. 여기 로직은 알아서 처리. (나는 로그 남기고 Continue 시킴, 나머지라도 설치)   

                     }

 

                     string sRegistryFontName = $"{sFontDisplayName} ({sFontStyleName}) (TrueType)";

                     bool isAlreadyInstalled = regFontRegKey.GetValue(sRegistryFontName) != null;

 

                     // 이미 설치된 Font는 Skip

                     if (isAlreadyInstalled || File.Exists(sFontDestPath))

                          continue;

 

                     try

                     {

                          File.Copy(file, sFontDestPath);

 

                          // 레지스트리 등록

                          using (RegistryKey regWrite = Registry.LocalMachine.OpenSubKey(sFontPath, true))

                          {

                               regWrite.SetValue(sRegistryFontName, sFontFileName);

                          }

 

                          AddFontResource(sFontDestPath);

 

                          // 시스템 전체에 Font가 변경되었다는 것을 알림 - 이것을 안 하면 재부팅될 때까지 Font가 안 나올 수 있음

                          SendMessage((IntPtr)0xFFFF, WM_FONTCHANGE, IntPtr.Zero, IntPtr.Zero);

                     }

                     catch (Exception ex)

                     {

                          // 설치 실패

                     }

                }

           }

 

           private static string GetFontDisplayName(string pFontPath)

           {

                try

                {

                     using (PrivateFontCollection pfc = new PrivateFontCollection())

                     {

                          pfc.AddFontFile(pFontPath);

                          pfc.AddFontFile(pFontPath);

 

                          if (pfc.Families.Length > 0)

                               return pfc.Families[0].Name;

                     }

                }

                catch

                {

                     // 에러가 나도 그냥 실행하기 위해서

                }

             

                return null;   

           }

     }

}

 

3. 이렇게 하고 프로그램을 실행하면 Custom Font가 설치된 것을 확인할 수 있다.

4. Custom Font가 적용되지 않으면, app.manifest파일을 만들어 관리자 권한으로 실행할 수 있도록 한다.

728x90
반응형
LIST

+ Recent posts