Powershell:为同一进程名称的多个应用程序设置窗口大小和位置

Powershell:为同一进程名称的多个应用程序设置窗口大小和位置

我正在使用来自在 PowerShell 5 和 6 中设置窗口大小和位置,这对于仅一个应用程序来说效果很好,但我需要打开同一进程的多个窗口,并且每次调用它们时,我都会将它们设置为某个位置。而不是将它们全部转到一个指定位置。

解决了: 最后确定了如何让它在服务器上工作。添加了参数 $ProcessTitle 以及 $UserSessionID,使其能够正常工作,但有时它在尝试将窗口移动到位时无法快速获得 $ProcessID,并且会出错。为了解决这个问题,我在 $ProcessID 为空时添加了 Start-Sleep,并在运行命令后将其重置回 $null。

While ($ProcessID -eq $Null){
$ProcessID = (Get-Process -name $ProcessName | Where-Object -property SI -eq $UserSessionID |where {$_.MainWindowTitle -eq $ProcessTitle}).Id 
Start-Sleep -Milliseconds 50}

功能脚本:

 Function Set-Window {

    [OutputType('System.Automation.WindowInfo')]
    [cmdletbinding()]
    Param (
        [parameter(ValueFromPipelineByPropertyName=$True)]
        $ProcessName,
        [int]$UserSessionID,
        [string]$ProcessTitle,
        [int]$X,
        [int]$Y,
        [int]$Width,
        [int]$Height,
        [switch]$Passthru

    )
    Begin {
        Try{
            [void][Window]
        } Catch {
        Add-Type @"
              using System;
              using System.Runtime.InteropServices;
              public class Window {
                [DllImport("user32.dll")]
                [return: MarshalAs(UnmanagedType.Bool)]
                public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);

                [DllImport("User32.dll")]
                public extern static bool MoveWindow(IntPtr handle, int x, int y, int width, int height, bool redraw);
              }
              public struct RECT
              {
                public int Left;        // x position of upper-left corner
                public int Top;         // y position of upper-left corner
                public int Right;       // x position of lower-right corner
                public int Bottom;      // y position of lower-right corner
              }
"@
        }
    }
    Process {
        $Rectangle = New-Object RECT
        While ($ProcessID -eq $Null){
        $ProcessID = (Get-Process -name $ProcessName | Where-Object -property SI -eq $UserSessionID |where {$_.MainWindowTitle -eq $ProcessTitle}).Id 
        Start-Sleep -Milliseconds 50}

        $Handle = (Get-Process -id $ProcessID).MainWindowHandle
        #$Handles = (Get-Process -Name $ProcessName).MainWindowHandle  
        #foreach ( $Handle in $Handles ) {                             
            if ( $Handle -eq [System.IntPtr]::Zero ) { Continue }    
            $Return = [Window]::GetWindowRect($Handle,[ref]$Rectangle)
            If (-NOT $PSBoundParameters.ContainsKey('Width')) {            
                $Width = $Rectangle.Right - $Rectangle.Left            
            }
            If (-NOT $PSBoundParameters.ContainsKey('Height')) {
                $Height = $Rectangle.Bottom - $Rectangle.Top
            }
            If ($Return) {
                $Return = [Window]::MoveWindow($Handle, $x, $y, $Width, $Height,$True)
            }
            If ($PSBoundParameters.ContainsKey('Passthru')) {
                $Rectangle = New-Object RECT
                $Return = [Window]::GetWindowRect($Handle,[ref]$Rectangle)
                If ($Return) {
                    $Height = $Rectangle.Bottom - $Rectangle.Top
                    $Width = $Rectangle.Right - $Rectangle.Left
                    $Size = New-Object System.Management.Automation.Host.Size -ArgumentList $Width, $Height
                    $TopLeft = New-Object System.Management.Automation.Host.Coordinates -ArgumentList $Rectangle.Left, $Rectangle.Top
                    $BottomRight = New-Object System.Management.Automation.Host.Coordinates -ArgumentList $Rectangle.Right, $Rectangle.Bottom
                    If ($Rectangle.Top -lt 0 -AND $Rectangle.LEft -lt 0) {
                        Write-Warning "Window is minimized! Coordinates will not be accurate."
                    }
                    $Object = [pscustomobject]@{
                        ProcessName = $ProcessName
                        Size = $Size
                        TopLeft = $TopLeft
                        BottomRight = $BottomRight
                    }
                    $Object.PSTypeNames.insert(0,'System.Automation.WindowInfo')
                    $Object            
                }

            }
    $ProcessID = $Null
    }
}

按钮点击

$btnPingFrame_Click = {
    $Per = $RestID + 'per'
    $Cer = $RestID + "cer"
    $R = $RestID + 'r'
    Get-Process |Where-Object {$_.MainWindowTitle -eq "PER - PROVIDER EDGE ROUTER"} | Stop-Process
    start-process cmd -ArgumentList "/C","mode con:cols=75 lines=19 && COLOR 0b && title PER - PROVIDER EDGE ROUTER&& ping $Per -t"
    Set-Window -ProcessName cmd -processtitle 'PER - PROVIDER EDGE ROUTER' -x 1 -y 1 -Width 615 -Height 345 -UserSessionID $UserSessionID -Passthru

    Get-Process |Where-Object {$_.MainWindowTitle -eq "CER - CUSTOMER EDGE ROUTER"} | Stop-Process
    start-process cmd -ArgumentList "/C","mode con:cols=75 lines=19 && COLOR 0a && title CER - CUSTOMER EDGE ROUTER&& ping $Cer -t"
    Set-Window -ProcessName cmd -processtitle 'CER - CUSTOMER EDGE ROUTER' -x 1 -y 335 -Width 615 -Height 345 -UserSessionID $UserSessionID -Passthru

    Get-Process |Where-Object {$_.MainWindowTitle -eq "R - AGGREGATED NETWORK"} | Stop-Process
    start-process cmd -ArgumentList "/C","mode con:cols=75 lines=19 && COLOR 0c && title R - AGGREGATED NETWORK&& ping $R -t"
    Set-Window -ProcessName cmd -processtitle 'R - AGGREGATED NETWORK' -x 1 -y 670 -Width 615 -Height 345 -UserSessionID $UserSessionID -Passthru
    }

答案1

我不会尝试改变窗口大小或位置。但是,至于这个...

有什么方法可以让我创建脚本来指向最新的进程 ID?

...当我弹出记事本以显示命令中的文本时,我做了类似的事情。代码找到最后一个最近的记事本实例,激活它并将输出粘贴在那里。

# Get-Process | Clip

Get-WmiObject -Class Win32_OperatingSystem | Clip

[void] [System.Reflection.Assembly]::LoadWithPartialName("'Microsoft.VisualBasic")

& "$env:WinDir\Notepad.exe"
Start-Sleep -Seconds 1

$a = Get-Process `
| Where-Object {$_.Name -eq "Notepad"} `
| Select -Last 1

Start-Sleep -Seconds 1

[Microsoft.VisualBasic.Interaction]::AppActivate($a.ID)
[void] [System.Reflection.Assembly]::LoadWithPartialName("'System.Windows.Forms")
[System.Windows.Forms.SendKeys]::SendWait("%EP")

相关内容