PowerShell 计算开始栏的像素高度

PowerShell calculate pixel height of Start Bar

我想在屏幕上的不同位置放置 windows。我可以如下计算屏幕的尺寸(如果有多显示器设置,这些是数组):

$widths = (Get-WmiObject -Class Win32_DesktopMonitor | Select-Object ScreenWidth).ScreenWidth
$heights = (Get-WmiObject -Class Win32_DesktopMonitor | Select-Object ScreenHeight).ScreenHeight

为了正确放置 windows,我还需要计算开始栏的高度。有谁知道如何使用 PowerShell 以编程方式收集开始栏高度?

我也想知道如何计算开始栏的位置(这样我就知道它是放在屏幕)如果可能?

您应该安全地使用 $Screen.WorkingArea 而不是使用 WMI,您可以使用例如 [System.Windows.Forms.Screen]::PrimaryScreen.

进行检索

话虽如此,下面的函数将为您提供特定屏幕的任务栏的尺寸和位置:

Add-Type -AssemblyName System.Windows.Forms

function Get-TaskBarDimensions {
    param (
        [System.Windows.Forms.Screen]$Screen = [System.Windows.Forms.Screen]::PrimaryScreen
    )        

    $device = ($Screen.DeviceName -split '\')[-1]
    if ($Screen.Primary) { $device += ' (Primary Screen)' }

    if ($Screen.Bounds.Equals($Screen.WorkingArea)) {
        Write-Warning "Taskbar is hidden on device $device or moved to another screen."
        return
    }


    # calculate heights and widths for the possible positions (left, top, right and bottom)
    $ScreenRect  = $Screen.Bounds
    $workingArea = $Screen.WorkingArea
    $left        = [Math]::Abs([Math]::Abs($ScreenRect.Left) - [Math]::Abs($WorkingArea.Left))
    $top         = [Math]::Abs([Math]::Abs($ScreenRect.Top) - [Math]::Abs($workingArea.Top))
    $right       = ($ScreenRect.Width - $left) - $workingArea.Width
    $bottom      = ($ScreenRect.Height - $top) - $workingArea.Height

    if ($bottom -gt 0) {
        # TaskBar is docked to the bottom
        return [PsCustomObject]@{
            X        = $workingArea.Left
            Y        = $workingArea.Bottom
            Width    = $workingArea.Width
            Height   = $bottom
            Position = 'Bottom'
            Device   = $device
        }
    }
    if ($left -gt 0) {
        # TaskBar is docked to the left
        return [PsCustomObject]@{
            X        = $ScreenRect.Left
            Y        = $ScreenRect.Top
            Width    = $left
            Height   = $ScreenRect.Height
            Position = 'Left'
            Device   = $device
        }
    }
    if ($top -gt 0) {
        # TaskBar is docked to the top
        return [PsCustomObject]@{
            X        = $workingArea.Left
            Y        = $ScreenRect.Top
            Width    = $workingArea.Width
            Height   = $top
            Position = 'Top'
            Device   = $device
        }
    }
    if ($right -gt 0) {
        # TaskBar is docked to the right
        return [PsCustomObject]@{
            X        = $workingArea.Right
            Y        = $ScreenRect.Top
            Width    = $right
            Height   = $ScreenRect.Height
            Position = 'Right'
            Device   = $device
        }
    }
}

仅获取主屏幕的任务栏尺寸:

Get-TaskBarDimensions

获取所有已连接屏幕的任务栏尺寸:

[System.Windows.Forms.Screen]::AllScreens | ForEach-Object {
    Get-TaskBarDimensions $_
}

这将 return 具有以下属性的对象:

X        : 0
Y        : 1160
Width    : 1920
Height   : 40
Position : Bottom
Device   : DISPLAY1 (Primary Screen)

或者 - 如果任务栏被隐藏或不出现在该屏幕上 - 警告如下:

Taskbar is hidden on device DISPLAY2 or moved to another screen.

只是为了分享@Theo 上面给我的信息的一些用途,我想制作一个可以定位 PowerShell 控制台的函数。这目前无法应对多显示器设置(如果有人想扩展功能,我会很高兴看到它!)。

我将它们保存为 lllrrr 以及 fff ("full size") 以便快速访问并将它们保存在我的 Custom-Tools 可用模块中我所有的控制台会话。 fff 依赖于 $host.UI.RawUI 方法,该方法不如设置 ConsolePosition 准确(我 trim 从高度偏移 1 个字符,因为有时它不适合这种方式)但我很漂亮很高兴能够以这种方式轻松翻转控制台设置。

function Global:Set-ConsolePosition ($x, $y, $w, $h) {
    # Note: the DLL code below should not be indented from the left-side
    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);
}
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"
}
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"
}
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"
    }
}