我找到了一个脚本here(请参见下文),该脚本使我可以从Powershell中选择一个主窗口,然后添加一些按键。但是,当脚本选择主窗口而不是对话框时,我想按一下以使其消失。是否有某种方法可以选择对话框,或者使用按键将其选中?
Function SendKey{
[CMDLetBinding()]
Param(
[String]
[Parameter(Mandatory=$True,ValueFromPipelineByPropertyName=$True,Position=1)]
$WindowTitle,
[String[]]
[Parameter(Mandatory=$True,ValueFromPipelineByPropertyName=$True,Position=2)]
$Key
)
Begin{
$ErrorActionPreference = 'SilentlyContinue'
$Dlls = @'
[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
'@
$WindowControl = Add-Type -MemberDefinition $Dlls -Name "Win32WindowControl" -namespace Win32Functions -passThru
}
Process{
$WindowHandle = Get-Process | Where-Object { $_.MainWindowTitle -Match $WindowTitle } | Select-Object -ExpandProperty MainWindowHandle
If($WindowHandle){
$WindowControl::SetForegroundWindow($WindowHandle)
Sleep 1
$FocusHandle = $WindowControl::GetForegroundWindow()
If($FocusHandle -eq $WindowHandle){
ForEach($Press in $Key){
[System.Windows.Forms.SendKeys]::SendWait("$Press")
}
}
}
}
}
答案 0 :(得分:1)
您的代码:
有一个附带的问题:$ErrorActionPreference = 'SilentlyContinue'
程序集从未加载到您的代码中,[System.Windows.Forms.SendKeys]::SendWait("$Press")
抑制了后续错误,因此System.Windows.Forms
悄然失败({{1} }
有一个基本问题:将Add-Type -AssemblyName System.Windows.Forms
与进程的主窗口一起使用确实会在该主窗口上设置焦点,即使打开了模式对话框也是如此-结果,击键可能无济于事。
最简单的解决方案是改用SetForegroundWindow()
类型的静态.AppActivate()
方法:
[Microsoft.VisualBasic.Interaction]
会正确激活属于目标应用程序的最前面的任何窗口-如果您按Alt键制表到应用程序,则会激活该窗口。例如,这可能是主窗口或打开的模式对话框。.AppActivate()
要测试代码:
在PowerShell窗口中,点源提供上述函数(在您的会话中定义)。
打开一个NotePad实例(运行Function SendKey {
[CmdletBinding()]
Param(
[String]
[Parameter(Mandatory = $True, Position = 1)]
$WindowTitle,
[String[]]
[Parameter(Mandatory = $True, Position = 2)]
$Key
)
Begin {
# Load the required assemblies.
Add-Type -AssemblyName System.Windows.Forms, Microsoft.VisualBasic
}
Process {
# Find the process with the main window title of interest.
$procId = (Get-Process | Where-Object { $_.MainWindowTitle -Match $WindowTitle }).Id
If ($procId) { # Target application's process found.
# Activate it by its process ID.
[Microsoft.VisualBasic.Interaction]::AppActivate($procId)
# Send the keystrokes.
ForEach ($Press in $Key) {
[System.Windows.Forms.SendKeys]::SendWait($Press)
}
}
}
}
)。
切换到新实例,并使文件打开对话框可见( Ctrl + O )。
切换回您的PowerShell窗口并运行notepad
应该激活记事本,关闭文件打开对话框,并在主窗口(文档)中键入SendKey Notepad '{ESC}o'
。
如果没有打开任何对话框,则o
应该无效,{ESC}
也应该出现在主窗口中。
注意事项:击键将发送到目标窗口/目标窗口的打开对话框中恰好具有键盘焦点的任何控件。
因此,如果您知道在发送按键时将打开哪个特定的窗口/对话框,则可以首先发送其他按键来激活所需的特定控件。
例如,如果您希望打开文件打开对话框,则可以先发送o
(相当于 Alt + N ),以确保{{1 }}文本框具有输入焦点。
例如,发送文件名%n
:File name: