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

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

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

Затем я надеялся, что смогу запустить WinMerge и отправлять нажатия клавиш для перехода по меню для создания отчета (Alt+T, R, Diff.html, [Enter]). Я не вижу способа сделать это из процесса Groovy и не нашел способа сделать это в сценарии летучей мыши. Я ищу что-то похожее на 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*

person Weezle    schedule 21.01.2014    source источник
comment
Возможно - да! Я рекомендую использовать команду diff, доступную практически в любой версии Unix. Будет намного проще выполнить эту задачу в Unix, используя другие инструменты, доступные в Unix.   -  person RaviH    schedule 21.01.2014
comment
Я ценю предложение @RaviH, и я могу прибегнуть к diff в крайнем случае, но я хотел бы сохранить программу на своем ПК (Windows), и я хотел бы использовать программу WinMerge, поскольку это надежный инструмент, который легко генерирует чтение/анализ файлов.   -  person Weezle    schedule 21.01.2014
comment
Я могу сделать это из powershell, вам достаточно этой партии? По сути, я бы просто изменил этот фрагмент, чтобы активировать WinMerge, а затем отправил ваши ключи. stackoverflow.com /questions/21036524/ Если вы можете заставить это работать из powershell, то мы можем инкапсулировать команду powershell для запуска внутри командного файла, подобного этому. superuser.com/questions/696467/   -  person Knuckle-Dragger    schedule 21.01.2014
comment
@Weezle - Вероятно, стоит переместить раздел «Правка» в отдельный вопрос, а не просто добавлять новый вопрос в исходное сообщение.   -  person Mark    schedule 22.01.2014
comment
@ Knuckle-Dragger Я смог заставить ваше предложение работать. Если вы сделаете это ответом, я приму его.   -  person Weezle    schedule 22.01.2014


Ответы (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}"
person Knuckle-Dragger    schedule 22.01.2014
comment
Следует отметить, что это не сработает, если PowerShell запускается планировщиком задач Windows: Scheduler">Сценарии Powershell, управляющие элементами рабочего стола, не работают с Планировщиком - person Gabriel Glenn; 22.09.2015

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

RunMe.bat

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

Генератедифффиле.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 для знать, какие ключи отправить.

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

person James L.    schedule 21.01.2014
comment
Мне было интересно, есть ли способ сделать это вне VB (желательно Groovy или bat). - person Weezle; 21.01.2014
comment
bat не имеет встроенной поддержки для отправки нажатий клавиш в программу. Извините, я думал, что вы ищете, как заставить работать VB SendKeys, а не что-то подобное SendKeys. - person James L.; 22.01.2014
comment
Стоит ли использовать такой сложный и болезненный подход, когда GNU Diff Utils (да, есть доступные двоичные файлы Windows) может сделать это так легко? Разве мы не можем быть достаточно открытыми, чтобы использовать правильную платформу/инструменты для работы? ИМХО - виндоз (каламбур) сильно его усложняет, потому что он не предназначен для автоматизации таких задач. Ответом на такие задачи является Unix. Windoze может только мечтать о богатстве и простоте цепочки инструментов Unix. Если и когда я вынужден использовать Windoze для таких вещей (что случается очень редко), я либо использую исполняемый файл GNU diff utils, либо устанавливаю Cygwin для эмуляции unix на Windoze. - person RaviH; 22.01.2014
comment
Вы, безусловно, имеете право на ваше предпочтение, @RaviH. Мне лично нравится, как WinMerge легко экспортирует файлы сравнения/сравнения в отчеты в формате HTML, что упрощает отображение и анализ элементов. Это функция, которую я не нашел с помощью diff. Может конечно и есть, просто я не видел. Тем не менее, спасибо за то, что предоставили еще несколько альтернатив. - person Weezle; 23.01.2014

Все, что я делаю, это: echo y | «Пакетному файлу требуется нажатие клавиши»

person Pete Hecht    schedule 02.08.2016
comment
Кажется, это упускает из виду исходный вопрос. OP хочет отправлять нажатия клавиш в пользовательский интерфейс, а не в пакетный файл. - person Beniaminus; 03.08.2016
comment
Мне нужно, чтобы это было сделано с помощью сценария Groovy или сценария летучей мыши. Это будет работать в графическом интерфейсе, если вы создадите новый пакетный файл с именем GUIBatchFile.bat, где содержимое будет echo y | «Пакетному файлу требуется нажатие клавиши», поэтому он будет работать в Windows в графическом интерфейсе или командной строке. - person Pete Hecht; 03.08.2016