代码之家  ›  专栏  ›  技术社区  ›  leeand00

如何使用powershell将焦点放在模态对话框上?

  •  1
  • leeand00  · 技术社区  · 6 年前

    我找到剧本了 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")
                    }
                }
            }
        }
    }   
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   mklement0    6 年前

    您的代码:

    • $ErrorActionPreference = 'SilentlyContinue' 抑制后续错误,以便 [System.Windows.Forms.SendKeys]::SendWait("$Press") System.Windows.Forms 程序集从未加载到代码中( Add-Type -AssemblyName System.Windows.Forms

    • 有一个基本问题:使用 SetForegroundWindow() 窗口确实会将焦点设置在主窗口上,即使模式对话框处于打开状态-结果是,击键可能毫无用处。

    [Microsoft.VisualBasic.Interaction] 类型是静态的 .AppActivate() 方法:

    • .AppActivate()
    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)
          }
    
        }
      }
    }   
    

    要测试代码:

    • 打开记事本实例(运行 notepad ).

    • 切换到新实例并使“文件打开”对话框可见( Ctrl+O键 ).

    • SendKey Notepad '{ESC}o'

    应激活记事本,取消“文件打开”对话框,然后 o 应该在主窗口(文档)中键入。

    如果没有打开对话框,则 {ESC} 应该没有效果 o 也应该出现在主窗口中。

    警告 :击键将被发送到目标窗口/目标窗口的“打开”对话框中恰好具有键盘焦点的任何控件。

    因此,如果您知道在发送击键时将打开哪个特定窗口/对话框,则可以首先发送其他击键来激活特定的感兴趣控件。

    %n Alt+N键 -第一,确保 File name: 例如,发送文件名 file.txt SendKey Notepad '%nfile.txt'