PowerShell脚本,用于打开四个不同的Windows资源管理器路径并定位每个窗口

时间:2017-06-09 08:53:07

标签: windows powershell powershell-ise

我正在尝试编写一个脚本,打开Windows资源管理器四次(每个窗口使用不同的路径),并将每个窗口放在屏幕的一角,以便它们覆盖相同的区域。该脚本将用于具有不同屏幕分辨率的机器上,理想情况下它应该基于窗口大小,但这不是绝对必须的,只要它们不重叠(我认为它将使用最小屏幕分辨率) on是1366x768)。

我是PowerShell脚本新手,所以我设法让一些的东西正常工作,我只是努力将它们整合在一起。我能够在我想要的地方打开四个独立的Windows资源管理器窗口:

ii $path1
ii $path2
ii $path3
ii $path4

我还可以使用-ComObject Internet Explorer 打开到设定的尺寸:

$IE = New-Object -ComObject Internetexplorer.application

$IE.Left = 0
$IE.Width = 500
$IE.Top = 0
$IE.Height = 500

$IE.Navigate($URL)

$IE.Visible = $True

我无法让它与Windows资源管理器一起使用。我还设法获得了显示器的分辨率:

$monitor = Get-Wmiobject Win32_Videocontroller
$monitor.CurrentHorizontalResolution
$monitor.CurrentVerticalResolution

不幸的是,这提供了2个分辨率,因为我有两个显示器,我不知道如何只为其中一个提取分辨率。另外,如果脚本只在一台只有一台显示器的机器上运行,我不知道这意味着什么。

因此,根据我目前的情况,我特别想知道:

  1. 如何将我的Windows资源管理器窗口打开到一定的大小和位置,就像我使用IE一样(不必与ii一起使用,任何有用的东西)
  2. 如何为监视器分辨率提取单个值,我可以通过一些数学来获得最佳大小。
  3. 感谢。

    编辑:我找到了一个快速解决方案,但它并不存在。通过检查shell可用的命令,并提出了这个:

    $Shell = New-Object -ComObject Shell.Application
    
    ii $path1
    ii $path2
    ii $path3
    ii $path4
    
    $Shell.TileHorizontally()
    

    这应该可行,因为用户可能只打开这四个窗口,而不是其他任何东西。不幸的是,TileHorizontally()适用于所有打开的窗口,但看起来ii命令的执行速度不够快,因为它们在脚本运行时不会平铺。一旦脚本已经打开,它们会再次运行它。我认为-Wait选项可以帮助我,但它似乎不适用于ii。有人看到了解决方案吗?

    编辑2 :我的当前代码,使用Set-Window删除了文档注释:

    Function Set-Window {
        [OutputType('System.Automation.WindowInfo')]
        [cmdletbinding()]
        Param (
            [parameter(ValueFromPipelineByPropertyName=$True)]
            $ProcessId,
            [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
            $Handle = (Get-Process -Id $ProcessId).MainWindowHandle
            $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]@{
                        Id = $ProcessId
                        Size = $Size
                        TopLeft = $TopLeft
                        BottomRight = $BottomRight
                    }
                    $Object.PSTypeNames.insert(0,'System.Automation.WindowInfo')
                    $Object            
                }
            }
        }
    }
    
    
    Get-Process -Id (Start-Process -FilePath C:\windows\explorer.exe -ArgumentList "." -Wait -Passthru).Id | Set-Window -X 500 -Y 500 -Height 500 -Width 500 -Passthru
    

0 个答案:

没有答案