Home > Enterprise >  PowerShell control maximise / restore for console window
PowerShell control maximise / restore for console window

Time:04-25

I have these handy functions to flip console sizes from the command line. The only problem is that they don't work if the console window is in the maximized state. Is there a way to toggle Maximize / Restore for the console window from the PowerShell prompt?

function Global:Set-ConsolePosition ($x, $y, $w, $h) {
    # Keep this function in ProfileExtensions as used during updates
    # Note: the DLL code below must not be indented from the left-side or will break
    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); '
    # 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);
}

# Does not "maximize" but sets the window to the maximum extent allowed by the screensize.
function Global:Set-MaxWindowSize {
    # Keep this function in ProfileExtensions as used during updates
    # This will open every new console pinned to top of screen and large size
    # 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' and 'Alt-Enter' to fullscreen the console`n"

    if ($Host.Name -match "console") {
        $MaxHeight = $host.UI.RawUI.MaxPhysicalWindowSize.Height - 5    # 1
        $MaxWidth = $host.UI.RawUI.MaxPhysicalWindowSize.Width - 15     # 15
        if ($MaxWidth -gt 175) { $MaxWidth = 175}
        $MyBuffer = $Host.UI.RawUI.BufferSize
        $MyWindow = $Host.UI.RawUI.WindowSize
        $MyWindow.Height = ($MaxHeight)
        $MyWindow.Width = ($MaxWidth-2)
        $MyBuffer.Height = (9999)
        $MyBuffer.Width = ($MaxWidth-2)
        # $host.UI.RawUI.set_bufferSize($MyBuffer)
        # $host.UI.RawUI.set_windowSize($MyWindow)
        $host.UI.RawUI.BufferSize = $MyBuffer
        $host.UI.RawUI.WindowSize = $MyWindow
    }
}

# Set the window to be half-screen, left side
function lll {
    Add-Type -AssemblyName System.Windows.Forms
    $Screen = [System.Windows.Forms.Screen]::PrimaryScreen
    $width = $Screen.WorkingArea.Width   # .WorkingArea ignores the taskbar, .Bounds is whole screen
    $height = $Screen.WorkingArea.Height
    $w = $width/2   13
    $h = $height   8
    $x = -7
    $y = 0
    Set-ConsolePosition $x $y $w $h

    $MyBuffer = $Host.UI.RawUI.BufferSize
    $MyWindow = $Host.UI.RawUI.WindowSize
    $MyBuffer.Height = 9999
    "`nWindowSize $($MyWindow.Width)x$($MyWindow.Height) (Buffer $($MyBuffer.Width)x$($MyBuffer.Height))"
    "Position : Left:$x Top:$y Width:$w Height:$h`n"
}

# Set the window to be half-screen, right side
function rrr {
    Add-Type -AssemblyName System.Windows.Forms
    $Screen = [System.Windows.Forms.Screen]::PrimaryScreen
    $width = $Screen.WorkingArea.Width   # .WorkingArea ignores the taskbar, .Bounds is whole screen
    $height = $Screen.WorkingArea.Height
    $w = $width/2   13
    $h = $height   8
    $x = $w - 20
    $y = 0
    Set-ConsolePosition $x $y $w $h

    $MyBuffer = $Host.UI.RawUI.BufferSize
    $MyWindow = $Host.UI.RawUI.WindowSize
    $MyBuffer.Height = 9999
    "`nWindowSize $($MyWindow.Width)x$($MyWindow.Height) (Buffer $($MyBuffer.Width)x$($MyBuffer.Height))"
    "Position : Left:$x Top:$y Width:$w Height:$h`n"
}

# Set the window to be full-size
function fff {
    Set-ConsolePosition -7 0 600 600
    if ($Host.Name -match "console") {
        $MaxHeight = $host.UI.RawUI.MaxPhysicalWindowSize.Height - 1
        $MaxWidth = $host.UI.RawUI.MaxPhysicalWindowSize.Width
        $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
        "`nWindowSize $($MyWindow.Width)x$($MyWindow.Height) (Buffer $($MyBuffer.Width)x$($MyBuffer.Height))`n"
    }
}

# Only run this the first time that Profile Extensions are run in this session (i.e. so that ". pect" will not reactivate this)
if ($null -eq $ProfileExtensionsFirstRun) {
    Set-ConsolePosition 75 0 600 600
    Set-MaxWindowSize
}

CodePudding user response:

I found a script online and tweaked it to set the current window to normal - put this near the top of your script

$Script:showWindowAsync = Add-Type -MemberDefinition @"
[DllImport("user32.dll")]
public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
"@ -Name "Win32ShowWindowAsync" -Namespace Win32Functions -PassThru
Function Set-WindowNormal()
{
$null = $showWindowAsync::ShowWindowAsync((Get-Process -Id $pid).MainWindowHandle, 1)
}

Now calling Set-WindowNormal should set the self window to normal. Put this where you want to normalize your window. (before the necessary function call most likely)

I can't seem to find a better answer really.

In the code above. There are several ways to show a window. https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-showwindow explains them. 1 is normal. 2 is minimized etc...

This is the answer I was able to find. Apparently this is a tricky question.

  • Related