如何判断PowerShell运行环境是ConHost还是Windows Terminal等终端,以避免窗口调整代码报错
如何判断PowerShell运行环境是ConHost还是Windows Terminal等终端,以避免窗口调整代码报错
我完全懂你那种每次打开PowerShell窗口光标都被任务栏挡住的烦躁!你的窗口调整脚本在ConHost里能完美解决问题,但到Windows Terminal就触发缓冲区大小报错,核心就是得先精准区分当前的终端环境,再决定要不要执行那些窗口调整逻辑。
下面给你几种靠谱的判断方式,以及修改后能兼容多终端的脚本方案:
一、判断终端环境的几种方法
1. 检查Windows Terminal专属环境变量
Windows Terminal会自动设置WT_SESSION环境变量,而ConHost、Cmder这类终端没有这个变量。直接用这个判断最简便:
# 判断是否在Windows Terminal中 $isWindowsTerminal = [bool]$env:WT_SESSION
2. 通过父进程判断(支持更多终端)
如果要覆盖Cmder、ConEmu这类其他终端,可以检查当前PowerShell进程的父进程名称:
$parentProcessId = (Get-CimInstance Win32_Process -Filter "ProcessId = $pid").ParentProcessId $parentProcessName = (Get-Process -Id $parentProcessId -ErrorAction SilentlyContinue).Name # 判断是否在Windows Terminal $isWindowsTerminal = $parentProcessName -eq 'WindowsTerminal.exe' # 判断是否在Cmder/ConEmu $isCmder = $parentProcessName -match 'ConEmu|Cmder' # 判断是否在原生ConHost $isConHost = $parentProcessName -eq 'conhost.exe'
二、修改你的脚本,添加环境判断逻辑
把你的窗口调整代码加上条件判断,只在原生ConHost环境下执行,就能避免Windows Terminal里的报错了。修改后的完整脚本如下:
function Global:Set-ConsolePosition ($x, $y, $w, $h) { Add-Type -Name Window -Namespace Console -MemberDefinition ' [DllImport("Kernel32.dll")] public static extern IntPtr GetConsoleWindow(); [DllImport("user32.dll")] public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int W, int H); ' $consoleHWND = [Console.Window]::GetConsoleWindow(); $null = [Console.Window]::MoveWindow($consoleHWND, $x, $y, $w, $h); } function Global:Set-WindowState([int]$Type) { $Script:showWindowAsync = Add-Type -MemberDefinition @" [DllImport("user32.dll")] public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow); "@ -Name "Win32ShowWindowAsync" -Namespace Win32Functions -PassThru $null = $showWindowAsync::ShowWindowAsync((Get-Process -Id $pid).MainWindowHandle, $Type) } function Set-WindowClose() { Set-WindowState 0 } function Set-WindowNormal() { Set-WindowState 1 } function Set-WindowMin() { Set-WindowState 2 } function Set-WindowMax() { Set-WindowState 3 } function Global:Set-MaxWindowSize { # 只在原生ConHost环境下执行窗口调整 $parentProcessId = (Get-CimInstance Win32_Process -Filter "ProcessId = $pid").ParentProcessId $parentProcessName = (Get-Process -Id $parentProcessId -ErrorAction SilentlyContinue).Name if ($parentProcessName -eq 'conhost.exe') { $MaxHeight = 32 $MaxWidth = 120 if ($MaxWidth -gt 120) { $MaxWidth = 120 } $MyBuffer = $Host.UI.RawUI.BufferSize $MyWindow = $Host.UI.RawUI.WindowSize $MyWindow.Height = $MaxHeight $MyWindow.Width = $MaxWidth $MyBuffer.Height = 9999 $MyBuffer.Width = $MaxWidth $host.UI.RawUI.BufferSize = $MyBuffer $host.UI.RawUI.WindowSize = $MyWindow } } # 同样只在ConHost里执行窗口位置和状态调整 $parentProcessId = (Get-CimInstance Win32_Process -Filter "ProcessId = $pid").ParentProcessId $parentProcessName = (Get-Process -Id $parentProcessId -ErrorAction SilentlyContinue).Name if ($parentProcessName -eq 'conhost.exe') { Set-WindowNormal Set-ConsolePosition 75 20 500 400 }
为什么原来的代码在Windows Terminal报错?
Windows Terminal和ConHost的缓冲区大小限制不一样,你设置的9999行缓冲区高度超过了Windows Terminal允许的最大值,所以会触发"Cannot set the buffer size because the size specified is too large or too small"的错误。通过环境判断跳过这段逻辑就解决问题了。
备注:内容来源于stack exchange,提问作者YorSubs




