3

I use the below functions in my $profile to get around the incredibly annoying fact that Windows opens 80+% of new PowerShell windows with the cursor position below the taskbar so I have to move the window before using.

However, this generates an error in Windows Terminal:

Exception setting "BufferSize": "Cannot set the buffer size because the size
specified is too large or too small. Actual value was 120,9999."

So, how do I determine if I am currently running in ConHost or in Windows Terminal (or other terminals? maybe Cmder has a different host type?), so that I can create a condition in my $profile to not run this resizing option when I am in 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); '
    # Maybe do the Add-Type outside of the function as repeating it in a session can cause errors?
    $consoleHWND = [Console.Window]::GetConsoleWindow();
    $consoleHWND = [Console.Window]::MoveWindow($consoleHWND, $x, $y, $w, $h);
    # $consoleHWND = [Console.Window]::MoveWindow($consoleHWND,75,0,600,600);
    # $consoleHWND = [Console.Window]::MoveWindow($consoleHWND,-6,0,600,600);
}

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 { # This will open every new console in a reasonable position with cursor position visible # Added new restriction for ultrawide screens to cap the width to 175 # https://gallery.technet.microsoft.com/scriptcenter/Set-the-PowerShell-Console-bd8b2ad1 # https://stackoverflow.com/questions/5197278/how-to-go-fullscreen-in-powershell # "Also note: 'Mode 300' or 'Alt-Enter' to fullscreen a Conhost window`n"

if ($Host.Name -match "console") {
    $MaxHeight = 32   # Setting to size relative to screen size: $host.UI.RawUI.MaxPhysicalWindowSize.Height - 5    # 1
    $MaxWidth = 120   # Setting to size relative to screen size: $host.UI.RawUI.MaxPhysicalWindowSize.Width - 15     # 15
    if ($MaxWidth -gt 120) { $MaxWidth = 120 }   # This is to handle ultra-wide monitors, was 175, but 100 is better
    $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.set_bufferSize($MyBuffer)
    # $host.UI.RawUI.set_windowSize($MyWindow)
    $host.UI.RawUI.BufferSize = $MyBuffer
    $host.UI.RawUI.WindowSize = $MyWindow
}

}

Set-WindowNormal Set-ConsolePosition 75 20 500 400

YorSubs
  • 1,087

2 Answers2

1

With props to Oisin Grehan in this GitHub comment, a simple but not always correct approach is to test for the presence of $env:WT_SESSION, which is only available in Windows Terminal sessions.

if ($env:WT_SESSION) { 
    # yes, windows terminal
} else {
    # nope
}

A more comprehensive solution, which requires PowerShell 7+, is suggested by Gerardo Grignoli:

function Get-ConsoleHostProcessId {
# Save Original ConsoleHost title   
$oldTitle=$host.ui.RawUI.WindowTitle; 
# Set unique console title.
$r=(New-Guid); 
$host.ui.RawUI.WindowTitle = "$r"; 
#Find console window by title, then find console PID.
$result = (tasklist.exe /FO LIST /FI "WINDOWTITLE eq $r") | Select-String -Pattern  "PID:*" -Raw

if ($null -ne $result) {
    $consolePid = [int]($result.SubString(5).Trim());
} else {
    $consolePid = 0;
}        
# Restore original ConsoleHost title.
$host.ui.RawUI.WindowTitle=$oldTitle;

return [int]$consolePid;

}

function Test-IsWindowsTerminal { $consolePid = Get-ConsoleHostProcessId; if ($consolePid -gt 0) { return (Get-Process -PID (Get-ConsoleHostProcessId)).ProcessName -eq "WindowsTerminal"; } return $false; }

0

Just put a branching code in your profile that checks for host type, using If/Then statement.

If ($Host.Name -match 'ISE')
{
    # Do ISE customizations
}

If ($Host.Name -notmatch 'ISE') { # Do console customizations }

If you are using many other shells that can load PS, then a switch statement can be used as well.

switch ($host.Name)
{
    'Windows PowerShell ISE Host' {
        # Do ISE customizations
    }
'ConsoleHost' {
    # Do console customizations
}

'Visual Studio Code Host' {
    # Do VSCode customizations
}

Default {}

}

postanote
  • 5,136