Программно отправлять нажатия клавиш в оконную программу в Groovy или bat-скрипте

Предыстория: мне нужно программно найти различия между двумя файлами. Я хочу использовать WinMerge для создания отчета (Инструменты -> Создать отчет), который я могу проанализировать, чтобы получить различия между двумя файлами. Мне нужно, чтобы это было сделано с помощью скрипта Groovy или скрипта bat.

Я надеялся, что WinMerge предложит параметры командной строки для генерации отчета, и тогда я смогу просто использовать объект Groovy Process для запуска WinMergeU.exe с аргументами. Нет такой удачи в соответствии с параметрами команды, которые я нашел для WinMerge.

Затем я надеялся, что смогу запустить WinMerge и отправить нажатия клавиш для перехода по меню для создания отчета (Alt+T, R, Diff.html, [Enter]). Я не вижу способа сделать это из Groovy Process, и я не нашел способ сделать это в скрипте летучей мыши. Я ищу что-то похожее на WshShell.Sendkeys в VB. Это погоня за диким гусем?

ОБНОВЛЕНИЕ / Ответ с PowerShell в файле bat: Я был заинтригован комментарием Knuckle-Dragger об использовании скрипта PowerShell в файле bat.

$folder = "C:\DevTools\WinMerge\WinMergeU.exe"
ii $folder
Start-Sleep -m 1000
[void][System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic')
[Microsoft.VisualBasic.Interaction]::AppActivate("WinMerge")
Start-Sleep -m 100
[void][System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms')
Start-Sleep -m 100
[System.Windows.Forms.SendKeys]::SendWait("%F")
[System.Windows.Forms.SendKeys]::SendWait("o")
[System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
[System.Windows.Forms.SendKeys]::SendWait("%T")
[System.Windows.Forms.SendKeys]::SendWait("r")
Start-Sleep -m 1000
[Microsoft.VisualBasic.Interaction]::AppActivate("Save As")
Start-Sleep -m 1000
[System.Windows.Forms.SendKeys]::SendWait("Diff.txt")
[System.Windows.Forms.SendKeys]::SendWait("{ENTER}")

Чтобы инкапсулировать это в командном окне, сохраните его в файл PowerShellScript.ps1:

start /b /wait powershell.exe -nologo -WindowStyle Hidden -sta *PowerShellScript.ps1*

3 ответа

Решение

Вот пример powershell для активации winmerge и отправки некоторых ключей.

РЕДАКТИРОВАТЬ: Уменьшено копирование паста с некоторыми переменными.NET. $SK = Sendkeys $AA = AppActivate $LRA = Reflect .NET.

$startapp = "C:\DevTools\WinMerge\WinMergeU.exe"
ii $startapp
$SK = "[System.Windows.Forms.SendKeys]::SendWait"
$AA = "[Microsoft.VisualBasic.Interaction]::AppActivate"
$LRA = "[void][System.Reflection.Assembly]::LoadWithPartialName"
Start-Sleep 1
$LRA+'("Microsoft.VisualBasic")'
$AA+'("WinMerge")'
Start-Sleep -m 100
$LRA+'("System.Windows.Forms")'
Start-Sleep -m 100
$SK+'("%F")'
$SK+'("o")'
$SK+'("{ENTER}")'
$SK+'("%T")'
$SK+'("r")'
Start-Sleep 1
$AA+'("Save As")'
Start-Sleep 1
$SK+'("Diff.txt")'
$SK+'("{ENTER}")'

Чтобы инкапсулировать это в командном окне, сохраните его в файл PowerShellScript.ps1: обратите внимание, немного изменил синтаксис команды, должен работать, если вы используете & {.\ Dot\source\path}

start /b /wait powershell.exe  -nologo -WindowStyle Hidden -sta -Command "& {.\PowerShellScript.ps1}"

Это то, что я собрал вместе без тестирования, и у меня нет WinMerge, поэтому тестирование на самом деле не вариант.

RunMe.bat

start "" "C:\Path\WinMerge.exe" "file1" "file2"
GenerateDiffFile.vbs

GenerateDiffFile.vbs

Set s = CreateObject("WScript.Shell")

wscript.sleep(1000) ' Sleep for 1 second to allow time for WinMerge to finish loading and merge the files

s.SendKeys("%tr")
wscript.sleep(250) ' Give time for dialog box to appear
s.SendKeys("Diff.html{Enter}")

Это полностью не проверено, но я думаю, что это очень близко к тому, что вам нужно... Вы можете видеть, что пакетный файл запускает WinMerge, передавая два файла для слияния в командной строке. Затем он запускает сценарий VBS, который останавливается достаточно долго, чтобы позволить запущенному WinMerge принимать ввод с клавиатуры. Я использовал эту страницу от Microsoft, чтобы узнать, какие ключи отправлять.

Я посылаю ключи в программы в течение многих лет. Он работает очень надежно, пока программа, в которую вы хотите отправить ключи, сохраняет фокусировку.

Все, что я делаю, это: эхо у | "Пакетный файл, требующий нажатия клавиши"

Другие вопросы по тегам