# 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());
}
}
}
# 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;
}
}
}