Как мне сфокусироваться на модальном диалоговом окне, используя powershell? - PullRequest
0 голосов
/ 25 октября 2018

Я нашел скрипт здесь (см. Ниже), который позволяет мне выбрать главное окно в 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 Ответ

0 голосов
/ 28 октября 2018

Ваш код:

  • имеет непредвиденную проблему: $ErrorActionPreference = 'SilentlyContinue' подавляет последующие ошибки, поэтому [System.Windows.Forms.SendKeys]::SendWait("$Press") тихо завершается с ошибкой, учитывая, что сборка System.Windows.Forms никогда не загружается в вашкод (Add-Type -AssemblyName System.Windows.Forms

  • имеет фундаментальную проблему: использование SetForegroundWindow() с окном процесса main действительно установит фокус на этом главном окне, даже когдамодальное диалоговое окно открыто - в результате нажатия клавиш могут ни к чему не приводить.

Самое простое решение - использовать вместо этого статический метод [Microsoft.VisualBasic.Interaction] типа .AppActivate():

  • .AppActivate() должным образом активирует любое окно, принадлежащее целевому приложению, в первую очередь - как если бы вы нажали alt-tabed для приложения. Это может быть главное окно или открытый модальный диалог, дляinstance.
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)
      }

    }
  }
}   

Чтобы проверить код:

  • В окне PowerShell укажите точку выше для указанной выше функции (определите ее в своем сеансе).

  • Открыть экземпляр NotePad (запустить notepad).

  • Переключитесь на новый экземпляр и сделайте диалоговое окно открытия файла видимым ( Ctrl + O ).

  • Вернитесь в окно PowerShell и запустите SendKey Notepad '{ESC}o'

Блокнот должен быть активирован, диалоговое окно открытия файла должно быть закрыто, а o должно быть напечатано в главном окне (документ).

Если диалоговое окно не открыто, то {ESC} не должно иметь никакого эффекта и o также должно появиться в главном окне.

Предупреждение :Нажатие клавиш будет отправлено любому элементу управления в диалоговом окне открытия целевого окна / целевого окна с фокусом клавиатуры.

Поэтому, если вы знаете, какое конкретное окно / диалоговое окно будет открыто во время отправки нажатий клавишсначала вы можете отправить дополнительные нажатия клавиш, которые активируют определенный интересующий элемент управления.

Например, если вы ожидаете, что откроется диалоговое окно открытия файла, вы можете отправить %n - эквивалент Alt+ N - сначала обеспечитьчто текстовое поле File name: имеет фокус ввода.Например, чтобы отправить имя файла file.txt: SendKey Notepad '%nfile.txt'

...