GP SoftwareTwitter
Opus FAQsManualCommandsObjects

Problem passing paths to external program

I’m trying to pass the paths of a dual lister to the WinMerge software but I’ve come across a bit of a bug. The bug can be reproduced by creating an empty folder and then creating two subfolders within that folder. The subfolders must contain a space in their name.

In my case like this

D:\testfolder\folder 1
D:\testfolder\folder 2

Then create a file or folder in each of the subfolders, anything will do. Now I display folder 1 on one side and folder 2 on the other side of opus and click the WinMerge button. WinMerge pops up and says both my paths are invalid. These are the paths that winmerge is getting.

Left: D:\testfolder\folder 1" D:\testfolder\folder
Right: D:\testfolder\folder 1\2"

If I close the lister and then navigate back to folder 1 and folder 2 and click the WinMerge button again WinMerge pops up with the correct paths and works ok. I’ve had this problem intermittently with WinMerge and wasn’t sure what was causing it, but after some testing I’ve found the procedure above causes the problem every time.

This is the code I’m using in my WinMerge button.

"C:\Program Files\WinMerge\WinMerge.exe" /r {leftpathshort} {rightpathshort}

I’ve tried leftpath and rightpath as well with the same results. Any idea?

Yeah, download Nudel's toolbar that already has the commands you are looking for here.

I've downloaded nudels toolsbar and copied his code (see below) into my button and it now seems to work all the time. Still don't understand why my button somtimes worked and sometimes didn't. If the syntax was wrong you would think it would fail all the time. Thanks for the link kenalcock.

"C:\program files\WinMerge\WinMergeU.exe" /r "{sourcepath$|noterm}" "{destpath$|noterm}" @nodeselect

Leo uses long file paths with quotes around them (in case any folder or file name contained spaces). The |noterm removes the ending termination character, which many external programs cannot handle.

But I wonder why the same command on the same folders sometimes work and sometimes doesn't. When I got the problem using the previous command closing and re-opening the lister would make the command work. Just pointing it out in case it's a bug that might also affect other areas.

I can't remember why now but there must have been some reason that I added the quotes around the two paths. Opus should add them automatically if they're not there and the path contains a space but I've put them in explicitly in the button for some reason. Maybe I found problems with WinMerge wanting all paths to have quotes around them, whether they contain spaces or not?

The |noterm part is definitely essential with WinMerge. It puts up an error if you give it a path with a \ at the end.

OK I guess not adding the |noterm bit on the end was causing problems intermittently.

I’ve been using Nudels code to pass path information to WinMerge for some time now and it’s works perfectly…..until today. I’ve found that if I’m comparing a top level drive, in my case D:\ , WinMerge complains that the path is invalid. This is because dopus is passing this string for the D drive lister as D:\” the “ should not be at the end. This problem only seems to occur at the drive level.

This is the code I’m using.

"C:\program files\WinMerge\WinMergeU.exe" /r "{leftpath|noterm}" "{rightpath|noterm}"
@nodeselect

And this is what is getting passed to WinMerge

Folder1 = U:\D Drive backup
Folder2 = D:\”

Folder 1 is fine but you can see the “ at the end of the Folder2 path.

So I’ve gone back to the code and removed the “ from the leftpath and rightpath parts of the code, so it looks like this.

"C:\program files\WinMerge\WinMergeU.exe" /r {leftpath|noterm} {rightpath|noterm}
@nodeselect

I’ve tested it in a few different locations, it seems to work ok, but I’m just wondering if removing the “ is going to cause me some problems in certan situations?

Jon coded the Opus Command Parser to be "smart" about adding quotes if required around paths like {file} and {sourcepath}, when they contain spaces. Opus 8 wasn't as "smart" as Opus 9 is. Also, depending on how you are using the file paths, you may not want them quoted. I got in the habit of suppressing all Opus automatic quoting using the @nofilenamequoting control code and manually adding quotes where I want them

It's actually a bug in WinMerge's command-line parsing. Opus is sending the right thing to WinMerge but WinMerge gets confused by a path ending with a \ if that path is quoted. The |noterm thing usually removes that last slash but not when it's just a drive letter (which is correct, a path like "C:" means something quite different to "C:", at least in a command prompt).

You can take Opus out of the picture and run this from a command prompt to confirm it's a problem in WinMerge:

"C:\program files\WinMerge\WinMergeU.exe" /r "C:\Documents and Settings" "C:"

A perfectly valid command-line but WinMerge will appear thinking you want to compare C:\Documents and Settings with C:" which is clearly wrong.

(Tested with WinMerge 2.6.6.0 Unicode)

I just played with it some more and I think the problem with WinMerge is that it interprets \ as an escape character (at least when it's next to a quote), so the " turns into a literal quote character.

Removing the quotes as you've done will probably make it work fine, since Opus will add the quotes back anyway if they are needed (i.e. if the path has a space in the name.

I thought there was also a way to tell Opus to generate paths with / instead of \ (as I once asked for this to help with some problems with command-line CVS clients) but I can't see how to do that now. Maybe it wasn't added in the end, or maybe it's there and I can't find it.

My analysis might be wrong there, thinking further. The " turns into a " so the \ isn't escaping the " after it. It's probably just a bug rather than an accidental feature.

Anyone with a SourceForge account feel like reporting this to the WinMerge folks so they can fix it? If not I'll try and remember to do it when I've got a moment.

Thanks for the info guys.

Having claimed it was a problem in WinMerge, I just realised the exact same thing happens with my SetClip program. (Well, I realised a long time ago but only just connected the two.)

So the " problems seem to be a bug or quirk in the command-line parsing done by Microsoft's C runtime library. (I assume that WinMerge is compiled using Visual Studio like my SetClip is. I just use the standard argv/argc arguments to main and the problem has already happened before any of my code has run.) Only solution would be to write your own command-line parsing code and use it instead of the C runtime code, but that doesn't seem worth it when there's a workaround.