如何在PowerShell中测量窗口的高度(行数)?

7

我的环境中最大行数为47。

我能否通过编程来测量这个值?

3个回答

11

为了补充Christian.K有用的答案

  • 获取主机对象的一个更简单、稍微更有效的方法是使用$Host自动变量而不是Get-Host命令。

  • 只有在PowerShell控制台主机中运行时,即控制台(终端)窗口中运行,您才能保证访问窗口大小信息

    • 它由给定主机决定是否公开此信息,并且正如Christian所述,PowerShell ISE不会这样做——尽管可以说它应该这样做,因为它内置了控制台子系统。
  • 测试代码是否正在运行于控制台(也称为终端中,请使用
    $Host.UI.SupportsVirtualTerminal——$True表示主机是控制台。


如果在PowerShell控制台主机中运行:

您可以通过以下方式之一访问控制台属性

  • 通过$Host.UI.RawUI(与Christian的答案中一样),这是一个类型为[System.Management.Automation.Internal.Host.InternalHostRawUserInterface]的对象,该对象只包装了.NET的[Console]类(仅适用于PowerShell控制台主机)(请参见下文)。

  • 通过.NET [Console];例如,要以这种方式获取窗口高度(行计数),请使用:

    • [Console]::WindowHeight

$Host.UI.RawUI输出示例:

PS> $Host.UI.RawUI

ForegroundColor       : DarkYellow
BackgroundColor       : DarkMagenta
CursorPosition        : 0,58
WindowPosition        : 0,0
CursorSize            : 25
BufferSize            : 160,9999
WindowSize            : 160,75
MaxWindowSize         : 160,94
MaxPhysicalWindowSize : 303,94
KeyAvailable          : True
WindowTitle           : Windows PowerShell

如果在PowerShell ISE中运行:

以PowerShell 5.1版本为例

$Host.UI.RawUI中的大部分属性都未被填充,将返回其数据类型的默认值:

PS> $Host.UI.RawUI  # in the ISE

ForegroundColor       : -1
BackgroundColor       : -1
CursorPosition        : 0,0
WindowPosition        : 
CursorSize            : 
BufferSize            : 166,0
WindowSize            : 
MaxWindowSize         : 
MaxPhysicalWindowSize : 
KeyAvailable          : 
WindowTitle           : Windows PowerShell ISE

唯一可用的与大小相关的信息是缓冲区宽度(在上面的示例输出中为166)。

在ISE中,除了查询/设置与外部程序通信所使用的字符编码[Console] :: OutputEncoding 之外,没有任何意义尝试使用.NET [Console] [1]

  • Initially in a session, trying to use the window-related members of [Console] causes exceptions, because the ISE does not allocate a console window on startup:

    # In a pristine session.
    PS> [Console]::WindowHeight
    The handle is invalid.     # EXCEPTION
    
  • While the ISE allocates a - hidden - console window on demand, namely the first time you run a console application in your session, that hidden console window's properties, as then reported on via [Console], do not reflect the properties of the simulated console that the ISE presents to the user.

    # chcp is a console application, so when it is run, 
    # the ISE allocates a (hidden) console window, 
    # after which the [Console] API becomes technically usable, 
    # but DOESN'T REPORT MEANINGFUL VALUES.
    PS> chcp >$null; [Console]::WindowHeight
    72  # No exception, but the value is meaningless.
    

[1] 请注意,ISE 默认使用系统的传统 ANSI 代码页,而普通控制台窗口默认使用 OEM 代码页。因此,默认情况下这两个环境会以不同的方式解码来自外部程序的输出。


谢谢,"[Console]::WindowHeight" 在 powershell_ise 中很好用。 - Hyundong Hwang
1
@HyundongHwang:很高兴听到这个消息,但这令人惊讶并且与我的答案相矛盾,所以让我们试着找出原因:(a) 当您将[Console]::WindowHeight粘贴到ISE中的控制台窗格中时,您确实会得到一个整数值(对我来说:上面描述的异常)吗?(b) (Get-Command powershell_ise).Version.ToString()报告了什么(对我来说:10.0.15063.0)?(c) $PSVersionTable.PSVersion.ToString()报告了什么(对我来说:5.1.15063.413)? - mklement0
是的,它与您的期望不同。 我打印了a、b和c值来进行调试,并截取了屏幕。https://s23.postimg.org/y2kgpxpff/screenshot_2017_07_03_at_09_19_22.png - Hyundong Hwang
@HyundongHwang,谜团解开了:像[Console]::WindowHeight这样的成员只有在您在会话中运行至少一个外部控制台应用程序后才开始工作,此时将分配一个隐藏的控制台窗口。但是,这些成员随后报告_隐藏_控制台窗口的属性,这些值与ISE呈现给用户的_模拟_控制台没有任何有意义的关系。简而言之:不要在ISE中使用[Console],除非查询/设置与外部程序通信所使用的_字符编码_,即[Console]::OutputEncoding - mklement0

4
您可以尝试类似以下的操作:
$(Get-Host).UI.RawUI.WindowSize.Height

请注意以下几点:
- 使用 RawUI 可能不太"便携",具体取决于脚本运行的位置。例如,在 "ISE" 中,该属性返回空值,而在控制台中它将起作用。 - 要了解控制台和 ISE 之间的更多差异,请运行 $(Get-Host).UI.RawUI 并比较输出。 - 在除控制台或 ISE 之外的其他 PowerShell 主机中,情况可能仍然不同。 - 还有一个 BufferSize,可以比 WindowSize 更大。后者只是用户当前可见部分。
你的问题听起来有些像xy问题。请考虑解释一下你实际想要实现的目标,即为什么需要知道行数?

感谢您的积极回应。 当我测试时,powershell_ise中没有值。 我想在需要分页的情况下创建一个对应于“more”的函数,以便在powershell_ise中使用。 现在我知道了powershell.exe中的最大行数,如果我能很好地应用它,那么它会对我有所帮助。 - Hyundong Hwang
1
好的,请注意,即使是内置的 more 在 ISE 中也无法工作。很可能是因为必要的信息在那里不可用。 - Christian.K

0

我真正需要的功能是在powershell_ise中使用git statusgit diff,并且希望有高亮和输出分页。

目前的powershell_ise版本似乎无法解决这个问题,虽然不完全令人满意,但我想出了一个实用的解决方案,并创建了以下函数。




源代码

function hhd-git-diff
{
    [CmdletBinding()]
    param
    (
    )

    $res = git diff
    hhd-git-colored-output -INPUT_OBJECT $res
}



function hhd-git-status
{
    [CmdletBinding()]
    param
    (
    )

    $res = git status
    hhd-git-colored-output -INPUT_OBJECT $res
}



function hhd-git-colored-output
{
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelinebyPropertyName=$true)]
        [System.Object]
        $INPUT_OBJECT
    )



    $lineNum = 1



    $INPUT_OBJECT | 
    Out-String | 
    foreach {

        $_ -split "\n" |

        foreach {

            if($lineNum % [Console]::WindowHeight -eq 0)
            {
                Read-Host "continue? press any key..."
            }

            $lineNum++

            if($_ -like "diff --git *")
            {
                Write-Host ""
                Write-Host ""
                Write-Host ""
                Write-Host ("#"*80) -ForegroundColor Cyan
                Write-Host $_ -ForegroundColor Cyan
                Write-Host ("#"*80) -ForegroundColor Cyan
                Read-Host "continue? press any key..."
                $lineNum = 1
            }
            elseif($_ -like "--- *")
            {
            }
            elseif($_ -like "+++ *")
            {
            }
            elseif($_ -like "-*")
            {
                Write-Host $_ -ForegroundColor Red
            }
            elseif($_ -like "+*")
            {
                Write-Host $_ -ForegroundColor Green
            }
            elseif($_ -like "On branch *")
            {
                Write-Host ("#"*80) -ForegroundColor Cyan
                Write-Host $_ -ForegroundColor Cyan
            }
            elseif($_ -like "Your branch is*")
            {
                Write-Host $_ -ForegroundColor Cyan
                Write-Host ("#"*80) -ForegroundColor Cyan
            }
            elseif($_ -like "Changes to be committed:*")
            {
                Write-Host ("-"*80) -ForegroundColor Green
                Write-Host $_ -ForegroundColor Green
            }
            elseif($_ -like "Changes not staged for commit:*")
            {
                Write-Host ("-"*80) -ForegroundColor Red
                Write-Host $_ -ForegroundColor Red
            }
            elseif($_ -like "Untracked files:*")
            {
                Write-Host ("-"*80) -ForegroundColor Black
                Write-Host $_ -ForegroundColor Black
            }
            elseif($_ -like "*modified:*")
            {
                Write-Host $_ -ForegroundColor Yellow
            }
            elseif($_ -like "*deleted:*")
            {
                Write-Host $_ -ForegroundColor Red
            }
            else
            {
                Write-Host $_ -ForegroundColor Gray
            }
        }
    }



}



屏幕截图


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接