본문 바로가기

C#/예제 코드

c# 콘솔 폰트 확인 및 폰트(글꼴,크기) 변경

사전지식 및 계기

특수문자 또는 외국문자를 출력하다 보면 폰트에 따라서 깨지는 글자가 생긴다.

특히 콘솔에서는 대체 폰트가 없는 듯이 깨진다.

그리고 글꼴이 맘에 안들 수가 있다.  그럴 땐 콘솔 창 타이틀바에 마우스 오른쪽을 클릭하여 속성 창에서 변경이 가능한데, 이번에는 c#코드로 런타임 때 변경하는 방법을 알아본다.


준비물

.net6.0 이상의 버전

에디터는 vs2022을 추천(권장)


실습

1. ConsoleHelper.cs 파일을 작성한다.

using System.Runtime.InteropServices;

public static class ConsoleHelper
{
    private const int FixedWidthTrueType = 54;
    private const int StandardOutputHandle = -11;
   
    [DllImport("kernel32.dll", SetLastError = true)]
    static extern IntPtr GetStdHandle(int nStdHandle);

    [return: MarshalAs(UnmanagedType.Bool)]
    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    static extern bool SetCurrentConsoleFontEx(IntPtr hConsoleOutput, bool MaximumWindow, ref FontInfo ConsoleCurrentFontEx);

    [return: MarshalAs(UnmanagedType.Bool)]
    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    static extern bool GetCurrentConsoleFontEx(IntPtr hConsoleOutput, bool MaximumWindow, ref FontInfo ConsoleCurrentFontEx);


    private static readonly IntPtr ConsoleOutputHandle = GetStdHandle(StandardOutputHandle);

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct FontInfo
    {
        internal int cbSize;
        internal int FontIndex;
        internal short FontWidth;
        public short FontSize;
        public int FontFamily;
        public int FontWeight;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
        public string FontName;
    }


    public static FontInfo GetCurrentFont()
    {
        FontInfo before = new FontInfo
        {
            cbSize = Marshal.SizeOf<FontInfo>()
        };

        if (!GetCurrentConsoleFontEx(ConsoleOutputHandle, false, ref before))
        {
            var er = Marshal.GetLastWin32Error();
            Console.WriteLine("Get error " + er);
            throw new System.ComponentModel.Win32Exception(er);
        }
        return before;
    }

    public static FontInfo[] SetCurrentFont(string font, short fontSize = 0)
    {
        Console.WriteLine("Set Current Font: " + font);

        FontInfo before = new FontInfo
        {
            cbSize = Marshal.SizeOf<FontInfo>()
        };

        if (GetCurrentConsoleFontEx(ConsoleOutputHandle, false, ref before))
        {

            FontInfo set = new FontInfo
            {
                cbSize = Marshal.SizeOf<FontInfo>(),
                FontIndex = 0,
                FontFamily = FixedWidthTrueType,
                FontName = font,
                FontWeight = 400,
                FontSize = fontSize > 0 ? fontSize : before.FontSize
            };

            // Get some settings from current font.
            if (!SetCurrentConsoleFontEx(ConsoleOutputHandle, false, ref set))
            {
                var ex = Marshal.GetLastWin32Error();
                Console.WriteLine("Set error " + ex);
                throw new System.ComponentModel.Win32Exception(ex);
            }

            FontInfo after = new FontInfo
            {
                cbSize = Marshal.SizeOf<FontInfo>()
            };
            GetCurrentConsoleFontEx(ConsoleOutputHandle, false, ref after);

            return new[] { before, set, after };
        }
        else
        {
            var er = Marshal.GetLastWin32Error();
            Console.WriteLine("Get error " + er);
            throw new System.ComponentModel.Win32Exception(er);
        }
    }
}

 

2. 테스트 소스를 작성한다. 

※ .net6.0 ( C#10.0 에서는 Main()을 생략한다 )

var info = ConsoleHelper.GetCurrentFont();

Console.WriteLine(info.FontName + ": " + info.FontSize);

ConsoleHelper.SetCurrentFont("궁서", 35);

Console.WriteLine();
Console.WriteLine("다람쥐 헌 쳇바퀴에 타고파");

 

고정폰트가 아닌 폰트는 글자가 붙어 버릴 수 있다.

 


주의사항

윈도우에 내장된 콘솔에 대해서만 동작을 보장한다..

vscode처럼 자체 콘솔 창이 있다면 높은 확률로 오류가 난다. 

 

글자가 너무 커져 버릴 땐 당황하지 않고 Ctrl + 마우스 휠로 조정 가능하다

 

 

 

참조:

https://docs.microsoft.com/en-us/dotnet/api/system.console?view=net-6.0

 

Console Class (System)

Represents the standard input, output, and error streams for console applications. This class cannot be inherited.

docs.microsoft.com