如何在PowerShell中找到最小屏幕BufferWidth?

发布于 12-27 13:14 字数 242 浏览 4 评论 0原文

我可以使用 $host.UI.RawUI.MaxPhysicalWindowSize.Width 获取 PowerShell 命令窗口的最大宽度(即列数),并且设置 PowerShell 命令窗口的大小有详细记录,但最小缓冲区宽度似乎不同机器之间有所不同。在一台机器上它是 13,但在另一台机器上它是 14。我可以将最小窗口高度和宽度设置为 1,最小缓冲区高度也可以为 1。

有谁知道我如何以编程方式获取这个最小缓冲区宽度值(而不只是尝试值并捕获异常!)

I can use $host.UI.RawUI.MaxPhysicalWindowSize.Width to get the maximum width (i.e. number of columns) for the PowerShell command window, and setting the size of the PowerShell command window is well documented, but the minimum buffer width seems to vary between machines. On one machine it was 13 but on another it was 14. I can set the minimum window height and width to 1 and the minimum buffer height can also be 1.

Does anyone know how I can obtain this minimum buffer width value programatically (without just trying values and catching the exceptions!)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

故事和酒2025-01-03 13:14:55

因为设置 $host.UI.RawUI.BufferSize 会影响其控制台屏幕的缓冲区,(命令提示符 -> 属性 -> 布局 -> 屏幕缓冲区大小为当您更改 $host.UI.RawUI.BufferSize 时进行修改),它的缓冲区大小与控制台屏幕具有相同的限制。

我们可以在此处阅读、指定的buffersize尺寸不能小于系统允许的最小尺寸。此最小值取决于控制台的当前字体大小(由用户选择)以及 GetSystemMetrics 函数。

这意味着控制台屏幕字体越大,缓冲区大小可以设置得越小。

举个例子:以下是如何获取控制台屏幕的最小宽度。我使用此高级函数从 User32.dll 中 P/Invoking GetSystemMetrics 函数(Joel Bennett 的 New-PInvoke) 。

$SM_CXMIN =28 # "The minimum width of a window, in pixels." enum value
New-PInvoke -Library User32.dll -Signature "int GetSystemMetrics(uint Metric)"
GetSystemMetrics $SM_CXMIN # returns 132 on my system

要检索控制台屏幕缓冲区使用的字体大小,请尝试 从 kernel32.dll 获取ConsoleFontSize

注意:

GetSystemMetrics $SM_CXMIN 返回的值是控制台屏幕的总宽度(包括边框)。

Because setting $host.UI.RawUI.BufferSize affects the buffer of its console screen, (Command Prompt -> Properties -> Layout -> Screen Buffer Size is modified when you change $host.UI.RawUI.BufferSize), it has the same restrictions on its buffersize as the console screen.

As we can read here, the specified dimensions for the buffersize cannot be less than the minimum size allowed by the system. This minimum depends on the current font size for the console (selected by the user) and the SM_CXMIN and SM_CYMIN values returned by the GetSystemMetrics function.

One implication of this, is that the larger your console screen font is, the smaller you can make the buffersize.

As an example: here's how to get the minimum width of a console screen. I'm P/Invoking the GetSystemMetrics function from User32.dll using this advanced function (New-PInvoke by Joel Bennett).

$SM_CXMIN =28 # "The minimum width of a window, in pixels." enum value
New-PInvoke -Library User32.dll -Signature "int GetSystemMetrics(uint Metric)"
GetSystemMetrics $SM_CXMIN # returns 132 on my system

To retrieve the size of the font used by the console screen buffer, try GetConsoleFontSize from kernel32.dll.

Note:

The value returned by GetSystemMetrics $SM_CXMIN is the total width (including the borders) of the console screen.

晨与橙与城2025-01-03 13:14:55

我在谷歌搜索中发现了这篇文章。由“jon Z”提供的“New-PInvoke by Joel Bennett”链接早已消失。使用互联网档案,我找到了 2015 年的一次捕获。为了保存,这里是该功能。

function New-PInvoke
{
    <#
    .Synopsis
        Generate a powershell function alias to a Win32|C api function
    .Description
        Creates C# code to access a C function, and exposes it via a powershell function
    .Example
        New-PInvoke -Library User32.dll -Signature "int GetSystemMetrics(uint Metric)"
    .Parameter Library
        A C Library containing code to invoke
    .Parameter Signature
        The C# signature of the external method
    .Parameter OutputText
        If Set, retuns the source code for the pinvoke method.
        If not, compiles the type.
    #>
    param(
    [Parameter(Mandatory=$true,
        HelpMessage="The C Library Containing the Function, i.e. User32")]
    [String]
    $Library,
   
    [Parameter(Mandatory=$true,
        HelpMessage="The Signature of the Method, i.e.: int GetSystemMetrics(uint Metric)")]
    [String]
    $Signature,
   
    [Switch]
    $OutputText
    )
   
    process {
        if ($Library -notlike "*.dll*") {
            $Library+=".dll"
        }
        if ($signature -notlike "*;") {
            $Signature+=";"
        }
        if ($signature -notlike "public static extern*") {
            $signature = "public static extern $signature"
        }
       
        $name = $($signature -replace "^.*?\s(\w+)\(.*$",'$1')
       
        $MemberDefinition = "[DllImport(`"$Library`")]`n$Signature"
       
        if (-not $OutputText) {
            $type = Add-Type -PassThru -Name "PInvoke$(Get-Random)" -MemberDefinition $MemberDefinition
            iex "New-Item Function:Global:$name -Value { [$($type.FullName)]::$name.Invoke( `$args ) }"
        } else {
            $MemberDefinition
        }
    }
}

I came across this post in my Google searches. The link for "New-PInvoke by Joel Bennett" provided by "jon Z" is long gone. Using the internet archive I found a single capture from back in 2015. For the sake of preservation here is the function.

function New-PInvoke
{
    <#
    .Synopsis
        Generate a powershell function alias to a Win32|C api function
    .Description
        Creates C# code to access a C function, and exposes it via a powershell function
    .Example
        New-PInvoke -Library User32.dll -Signature "int GetSystemMetrics(uint Metric)"
    .Parameter Library
        A C Library containing code to invoke
    .Parameter Signature
        The C# signature of the external method
    .Parameter OutputText
        If Set, retuns the source code for the pinvoke method.
        If not, compiles the type.
    #>
    param(
    [Parameter(Mandatory=$true,
        HelpMessage="The C Library Containing the Function, i.e. User32")]
    [String]
    $Library,
   
    [Parameter(Mandatory=$true,
        HelpMessage="The Signature of the Method, i.e.: int GetSystemMetrics(uint Metric)")]
    [String]
    $Signature,
   
    [Switch]
    $OutputText
    )
   
    process {
        if ($Library -notlike "*.dll*") {
            $Library+=".dll"
        }
        if ($signature -notlike "*;") {
            $Signature+=";"
        }
        if ($signature -notlike "public static extern*") {
            $signature = "public static extern $signature"
        }
       
        $name = $($signature -replace "^.*?\s(\w+)\(.*
quot;,'$1')
       
        $MemberDefinition = "[DllImport(`"$Library`")]`n$Signature"
       
        if (-not $OutputText) {
            $type = Add-Type -PassThru -Name "PInvoke$(Get-Random)" -MemberDefinition $MemberDefinition
            iex "New-Item Function:Global:$name -Value { [$($type.FullName)]::$name.Invoke( `$args ) }"
        } else {
            $MemberDefinition
        }
    }
}
浮云落日2025-01-03 13:14:55

也许我错了,但

[system.console]::BufferWidth 

你得到了实际的缓冲区宽度大小。

该值不能小于当前的 [System.Console]::WindowWidth 大小(将引发异常)。

Maybe I'm in wrong but with

[system.console]::BufferWidth 

you get the actual buffer width size.

This value can't be less than the current [System.Console]::WindowWidth size (will throw an exception).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文