Jay*_*kul 6 c# windows console powershell pinvoke
我不能让这个用于16个字符或更长的字体名称,但控制台本身显然没有这个限制.有没有人知道一种程序化的方式来设置与内置的"Lucida Sans打字机"或开源"Fira Code Retina"一起使用的字体?
我从各个地方复制了PInvoke代码,特别是PowerShell控制台主机和Microsoft Docs
请注意,CONSOLE_FONT_INFOEX和SetCurrentConsoleFontEx的相关文档没有谈到这一点,结构将字体定义为大小为32的WCHAR字段...
还要注意什么不是限制,而是是从控制台对话框的限制,是字体必须有真正的类型列出,而且必须是真正的固定宽度.使用此API,您可以选择"Times New Roman"等可变宽度字体...
但是,在API中,名称中必须少于 16个字符 - 这是控制台本身没有的限制,可能是API中的错误而不是我的下面的代码
using System;
using System.Runtime.InteropServices;
public static class ConsoleHelper
{
private const int FixedWidthTrueType = 54;
private const int StandardOutputHandle = -11;
[DllImport("kernel32.dll", SetLastError = true)]
internal static extern IntPtr GetStdHandle(int nStdHandle);
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
internal static extern bool SetCurrentConsoleFontEx(IntPtr hConsoleOutput, bool MaximumWindow, ref FontInfo ConsoleCurrentFontEx);
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
internal 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)]
//[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.wc, SizeConst = 32)]
public string FontName;
}
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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
您可以使用Add-Type该代码在PowerShell窗口中使用它,然后执行以下操作:
[ConsoleHelper]::SetCurrentFont("Consolas", 16)
[ConsoleHelper]::SetCurrentFont("Lucida Console", 12)
Run Code Online (Sandbox Code Playgroud)
然后,使用控制台"属性"对话框并手动切换到Lucida Sans Typewriter...并尝试只更改字体大小,指定相同的字体名称:
[ConsoleHelper]::SetCurrentFont("Lucida Sans Typewriter", 12)
Run Code Online (Sandbox Code Playgroud)
你会得到这样的输出(显示三个设置:之前,我们尝试过,我们得到了什么):
Set Current Font: Lucida Sans Typewriter
FontSize FontFamily FontWeight FontName
-------- ---------- ---------- --------
14 54 400 Lucida Sans Type?
12 54 400 Lucida Sans Typewriter
12 54 400 Courier New
Run Code Online (Sandbox Code Playgroud)
你在"之前"值的末尾看到那个奇怪的字符?只要字体长度超过16个字符就会发生这种情况(由于API或编组问题,我得到了垃圾数据).
实际的控制台字体名称显然不受长度限制,但也许不能使用名称长度为16个字符或更长的字体?
为了它的价值,我发现了Fira Code Retina的这个问题,这个字体在名称中只有16个字符 - 如果你想要试验的话,我在这里的代码比上面的代码多一点......
| 归档时间: |
|
| 查看次数: |
253 次 |
| 最近记录: |