Question

Backstory: I need to programmatically find the differences between two files. I want to use WinMerge to generate a report (Tools -> Generate Report) that I can parse to get the differences between two files. I need this done using either a Groovy script or a bat script.

I was hoping that WinMerge would offer command line options to generate the report and then I could just use a Groovy Process object to execute WinMergeU.exe with the arguments. No such luck according to the command options I've found for WinMerge.

Next, I was hoping to be able to start WinMerge and send keystrokes to step through the menus to generate the report(Alt+T, R, Diff.html, [Enter]). I don't see a way to do that from a Groovy Process and I haven't found a way to do this in a bat script. I'm looking for something similar to WshShell.Sendkeys in VB. Is this a wild-goose chase?

UPDATE/Answer with PowerShell in a bat file: I was intrigued by Knuckle-Dragger's comment about using a PowerShell script in a bat file.

$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}")

To encapsulate this in a command window, save it to a file PowerShellScript.ps1:

start /b /wait powershell.exe -nologo -WindowStyle Hidden -sta *PowerShellScript.ps1*
Was it helpful?

Solution

Here is a powershell example to activate winmerge and send some keys.

EDIT: Reduced copy pasta with some .NET variables. $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}")'

To encapsulate this in a command window, save it to a file PowerShellScript.ps1: Note, changed the command syntax a bit, should work if you use the & {.\dot\source\path}

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

OTHER TIPS

This is something that I threw together without testing, and I don't have WinMerge so testing isn't really an option.

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}")

This is completely untested, but I think it is very close to what you need... You can see that the batch-file runs WinMerge, passing the two files to merge on the command line. Then it launches the VBS script, which pauses long enough to allow the launched WinMerge to be able to accept keyboard input. I used this page from Microsoft to know what keys to send.

I've been sending keys to programs for years. It works very reliably, as long as the program you want to send keys to keeps focus.

All I do is this: echo y | "Batchfile needing the keystroke"

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top