首页 > 解决方案 > 检测 PowerShell 会话正在使用哪种字体

问题描述

我需要一种方法来检测 PowerShell 当前正在使用哪种字体,因此如果它处于活动状态,我可以从该字体发出某些字符(字形)。但是,如果字体未激活,我需要知道,这样我就可以避免从模块中发出这些字形。

问题:有没有办法检测当前在 PowerShell 会话中使用的字体,例如在 iTerm2 (Mac)、VSCode 或 Windows 终端中运行?

我检查了内置$Host变量,看它是否有类似的东西,但除了前景色之外,没有任何与字体相关的属性。

ForegroundColor       : Gray
BackgroundColor       : Black
CursorPosition        : 0,43
WindowPosition        : 0,0
CursorSize            : 25
BufferSize            : 164,44
WindowSize            : 164,44
MaxWindowSize         : 164,44
MaxPhysicalWindowSize : 3824,132
KeyAvailable          : True
WindowTitle           : PowerShell

标签: powershell

解决方案


以下脚本可能会有所帮助。

if ( -not ('Win32test.ConsoleTest' -as [type]) ) {
$defConsoleTest = @'
using System.Runtime.InteropServices;
using System;

namespace Win32test
{
    public static class ConsoleTest
    {
        [DllImport( "kernel32.dll", 
                    CharSet = CharSet.Unicode, SetLastError = true)]
        extern static bool GetCurrentConsoleFontEx(
            IntPtr hConsoleOutput,
            bool bMaximumWindow,
            ref CONSOLE_FONT_INFOEX lpConsoleCurrentFont);

        private enum StdHandle
        {
            OutputHandle = -11  // The standard output device.
        }

        [DllImport("kernel32")]
        private static extern IntPtr GetStdHandle(StdHandle index);

        public static string GetFontCsvHeader(){
            return  "FaceName,FontFamily,FontWeight,FontSize";
        }

        public static string GetFontCsv()
        {
            // Instantiating CONSOLE_FONT_INFOEX and setting cbsize
            CONSOLE_FONT_INFOEX ConsoleFontInfo = new CONSOLE_FONT_INFOEX();
            ConsoleFontInfo.cbSize = (uint)Marshal.SizeOf(ConsoleFontInfo);

            GetCurrentConsoleFontEx( GetStdHandle(StdHandle.OutputHandle),
                                     false, 
                                     ref ConsoleFontInfo);

            return  ConsoleFontInfo.FaceName + 
              "," + ConsoleFontInfo.FontFamily + 
              "," + ConsoleFontInfo.FontWeight + 
              "," + ConsoleFontInfo.dwFontSize.X + 
                    "×" + ConsoleFontInfo.dwFontSize.Y;
        }

        [StructLayout(LayoutKind.Sequential)]
        private struct COORD
        {
            public short X;
            public short Y;

            public COORD(short x, short y)
            {
            X = x;
            Y = y;
            }
        }

        // docs.microsoft.com/en-us/windows/console/console-font-infoex
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        private struct CONSOLE_FONT_INFOEX
        {
            public uint  cbSize;
            public uint  nFont;
            public COORD dwFontSize;
            public int   FontFamily;
            public int   FontWeight;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
            public string FaceName;
        }
    }
}
'@
Add-Type -TypeDefinition $defConsoleTest
}

# convert output to a pscustomobject
[Win32test.ConsoleTest]::GetFontCsvHeader(), 
[Win32test.ConsoleTest]::GetFontCsv() |
    ConvertFrom-Csv -Delimiter ','

在Windows 10中测试的输出,包括 Powershell5.1和 PwSh 7.0.1(控制台以及 VSCode 终端):

D:\PShell\tests\GetCurrentConsoleFontEx.ps1
FaceName    FontFamily FontWeight FontSize
--------    ---------- ---------- --------
Courier New 54         400        11×20

来自 Windows 的相同输出cmd

powershell -nopro -comm "& {D:\PShell\tests\GetCurrentConsoleFontEx.ps1}"
pwsh -nopro -comm "& {D:\PShell\tests\GetCurrentConsoleFontEx.ps1}"

推荐阅读