我正在尝试使用此答案中给出的脚本 在 PowerShell 5 和 6 中设置窗口大小和位置
设置多个 Windows 资源管理器窗口的高度和大小。不是互联网浏览器,而是名为“explorer”的文件浏览器。
它可以与程序“notepad”一起使用,但不能与程序“explorer”一起使用。
#works
Set-Window -ProcessName notepad-X 400 -Y 400 -Width 400 -Height 700
#doesnt work
Set-Window -ProcessName explorer -X 400 -Y 400 -Width 400 -Height 700
理想情况下我想要一个脚本:
- 打开 3 个资源管理器窗口。
- 导航到文件路径 A,B,C
- 将每个窗口的大小调整到屏幕上的特定位置
如何在不安装任何额外软件的情况下仅使用原始 powershell 来做到这一点?
编辑:在使用 harrymc 的建议后,我已经解决了一半的问题。我可以移动窗口,但我只需要弄清楚如何获取 3 个资源管理器子进程的句柄......
$MethodDefinition = @'
[DllImport("user32.dll")]
public extern static bool MoveWindow(IntPtr handle, int x, int y, int width, int height, bool redraw);
'@
$Kernel32 = Add-Type -MemberDefinition $MethodDefinition -Name 'Kernel32' -Namespace 'Win32' -PassThru
# How do I get 3 child explorer IDs here?
# i can't pass in 'explorer' name because that references the parent process running the whole GUI
$Handle = (Get-Process -Name "notepad").MainWindowHandle
$Return = [Window]::MoveWindow($Handle, 10, 20, 400, 400,$True)
编辑2:
我尝试通过 Start-Process 函数获取资源管理器窗口但收到错误:
$er3 = (Start-Process explorer -passthru)
PS C:\> (Get-Process -Id $er3.Id).MainWindowHandle
Get-Process : Cannot find a process with the process identifier 10572.At line:1 char:2
+ (Get-Process -Id $er3.Id).MainWindowHandle
+ ~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (10572:Int32) [Get-Process], ProcessCommandException
+ FullyQualifiedErrorId : NoProcessFoundForGivenId,Microsoft.PowerShell.Commands.GetProcessCommand
它说它已经退出了...但是资源管理器文件浏览器窗口仍然打开...不知道这里发生了什么。如果我用记事本试试,它就起作用了...
$er4 = (Start-Process notepad -passthru)
PS C:\> (Get-Process -Id $er4.Id).MainWindowHandle
9899994
编辑 3:我已经弄清楚了使用 ComObject 并访问 item(0)。
$ex4 = New-Object -ComObject Shell.Application
$ex4.open("C:\")
# $ex4.windows()[0].Width = 400 # breaks
$ex5 = $ex4.Windows()[0]
$ex6 = $ex5.Item(0) # not sure why i need to do this extra step
$ex6.Width = 400
$ex6.Navigate("file:///C:/Folder1/Folder2")
答案1
通过使用原生 Windows API 应该可以实现。如下所示:
[DllImport("User32.dll")]
public extern static bool MoveWindow(IntPtr handle, int x, int y, int width, int height, bool redraw);
...
$Handle = (Get-Process -Id $ProcessId).MainWindowHandle
$Return = [Window]::MoveWindow($Handle, $x, $y, $Width, $Height,$True)
由于此通用代码不适用于 Explorer,因此这里有一个替代解决方案(已测试):
$ex1 = New-Object -ComObject Shell.Application
$ex1.open("C:\")
$ex1.windows()[0].Top = 10
# also assignable : Left, Width, Height
# if required : $handle = $ex1.windows()[0].HWND
答案2
PowerShell 确实不是 UI 自动化工具。根据您所指出的,为什么不直接使用...
$w = Get-UIAWindow -ProcessName notepad
$w.Move(100, 100)
项目介绍
当您进行 GUI 测试时,UIAutomation 模块可简化软件测试自动化。该模块基于自 3.0 以来成为 .Net Framework 一部分的 UI Automation 库,旨在让软件工程师的生活尽可能轻松。
WASP 是一个 PowerShell 管理单元,用于执行 Windows 自动化任务,例如选择窗口和控件以及发送鼠标和键盘事件。我们有 Select-Window、Select-Control、Send-Keys、Send-Click、Get-WindowPosition、Set-WindowPosition、Set-WindowActive、Remove-Window 等 cmdlet
注意:这些不再维护,但它仍按设计工作,并且您使用从未或永远不会维护的示例代码。
另请参阅这个完全维护的解决方案:
AutoIt 脚本语言的最新版本现在为 PowerShell 用户带来了福利。一组原生的 PowerShell 命令!这允许您将 AutoIt 的独特功能(窗口操作和按键模拟)添加到您常用的 PowerShell 脚本中。作为额外的福利,AutoIt PowerShell 命令和程序集经过数字签名,因此可以与更严格的执行策略一起使用。这些命令还将与 x86 和 x64 版本的 PowerShell 一起原生运行!