Driving 3rd-Party Comparisons in x2 (A Paradigmatic Utility)

A collection of especially useful xplorer² topics and ideas. New users may find it helpful to look here before searching the other forums for information. >>>>>> Please post new material in the relevant forum. (New stuff posted here will be removed.) Thanks. -fg-

Moderators: fgagnon, nikos

Post Reply
Platinum Member
Platinum Member
Posts: 4569
Joined: 2008 Sep 30, 06:52
Location: Dublin

Driving 3rd-Party Comparisons in x2 (A Paradigmatic Utility)

Post by Kilmatead » 2014 Mar 16, 18:39

If you don't use 3rd-party comparison programmes such as WinMerge, WinDiff, Beyond Compare, ExamDiff, or any of a hundred others, then stop reading now.

If you're happy with how you pass arguments to those utilities now (such as using their shell-extensions or your own user-commands) and don't want to change, then stop reading now.

If you don't have peripheral awareness of your whole x2 working environment, stop reading now (I'm not kidding).

If, as the Americans say, you're not smarter than a 5th grader, please stop reading now.

If you don't know what a paradigmatic utility might be, continue reading (cautiously, with guns drawn...).

Still here? Ok, let's go...

Download: CompareHandler (Version, updated 16-Mar-2014)

As utilities go, this is my bête noire, my Trafalgar. I've probably re-written it from scratch at least six times over the last few years, and this is the current (and most robust) incarnation. What sounds simple in design turns out to be infuriatingly complex in execution. Essentially it launches (in a single-click) a 3rd-party comparison utility with selection-arguments based on the current x2 cross-pane-environment you're using, deriving those arguments from a fixed set of rules.

The primary logic sequence is simple:
  • a) If no objects are selected (in either pane) the pane-paths themselves are compared

    b) If any 2 items are selected in any active pane (including the miniscrap), they are compared to each other

    c) If 1 item is selected in the active pane, and 1 item in the inactive pane, they are compared

    d) If a single item is selected in one pane and it is a folder (or folder-type such as an archive), and nothing is selected in the opposite pane, the selected folder will be compared to the opposite pane's path

    * Left/Right orientation is always preserved between x2 and the comparison utility (this is half the benefit), irrespective of active pane or pane-type, or selection-position
Now on the face of it, this doesn't sound that complex - after all it's only 4 rules to remember, how tough can it be? The difficulty is borne by the user's awareness of what he has (and hasn't) selected, how he might intend those items to be handled, and getting the results he expects. The benefit is a simple, consistent, logical method of selecting and comparing files and folders quickly in a dynamic environment (the dual panes of x2 are always in tandem with the dual panes of the comparer) - with the added ability to modify the aspect of your selections in real-time before the comparison is actually launched. As anyone who has ever tried knows, this is very difficult to achieve using a static User-Command, and the shell extensions designed by the comparison utilities themselves often fall short, designed as they are for a single-pane explorer environment.

While the utility is actually designed to be predominantly used without its built-in menu, holding <Ctrl> when launching (or using the /Menu option) will popup a menu which allows the user to toggle various options before the arguments are committed - such as preventing common user-errors like accidentally comparing mis-matched object-types, or not supplying enough arguments - to reversing the order of arguments, or dismissing superfluous selections and enabling 3-way comparisons (assuming the comparer you use can support that ability).


The states of these toggled-options are not remembered between sessions (this is by design), so if you don't like the defaults as presented, you may need to use command-line parameters when creating the user-command:


Most of these are self-explanatory, and indeed, suggest how this utility is meant to behave, or even launched in the first place. Which brings us to the syntax of the user-command itself, which at its most basic will always be:

> CompareHandler.EXE /Run="{Path to Comparison Utility}" "$L" "$R" $A

Any other options may be added to the line as desired, but these 4 elements must always be present - in particular the last three literal tokens (first two in quotes, last one without) directly in that order. If you accidentally do not supply them all, or mess with the syntax, you are guaranteed to break the expected functioning. :wink:

Obviously, the /Run command expects a full path to your 3rd-party comparer's binary, wherever you have it installed, for example:

/Run="C:\Program Files (x86)\Beyond Compare 4\BCompare.exe"

Other commands, such as /3Way and /NoSeclude go towards how actual selections are handled between panes and/or the mini-scrap panel in particular. By default the mini-scrap is "secluded", meaning (unlike normal panes) at least two selections must be made for comparison and nothing outside of the mini-scrap is considered. However, by not "secluding" it, if the mini-scrap has focus and only one item is selected, and one (or more) items are selected in the Left/Right panes, the mini-scrap selection will be compared to the other selection(s). This can take a bit of getting used to as a paradigm, which is why it's switched off by default, always secuding the mini-scrap. By the same token, any selections over the first two are usually ignored (it's rather rare to need 3-way merge), so the "third item" (if selected) is not sent to the comparer, preventing odd conflicts. However, should the user require it (and the comparer be able to handle it) selecting 3-Way merge support is available, just disabled by default.

CompareHandler itself has three caveats which apply, and all three are equally important: 1) The user must use the correct "bit"-type for his x2-version, in other words x64 with x64 or x86 with x86. 2) The user must not have the "Hide extensions of known filetypes" option ticked in Windows Explorer. 3) The "Name" column must be configured to be first in the details column listing.

In case anyone is wondering why the "bit-type" is important, it's because I'm using an extreme method of deriving the selections directly from the listviews in x2. The reason this is needed is it allows me to keep the pane-order intact (regardless of "active" status) and completely avoids x2's habit of "sometimes" considering "focused" objects as "selected" even when they expressly are not. This way what the users actually selects and de-selects is axiomatic, and not to be confused (as often happens when using x2 tokens in user-commands) with any mystical "third-state" which only exists in Nikos' head. :D

One aspect of x2 integration which scripters tend not to make much use of is x2's built-in Filetype definitions, which are most often used when filtering and (frankly) not used for much else beyond that. In this case, I've tapped into them for automatically determining the filetype-extension matching rules - they are read directly from the registry (or use /INI if necessary), so the user doesn't need to do any special management once everything is up and running - any edits within x2 will be reflected by CompareHandler directly.


For example, when the user is comparing two or more files (as opposed to folders) if the types are in the same "group" (even if the extensions are different) they will be considered as an ok match and no error will occur. Simillarly, if two extensions are the same (even if they belong to none of the groups) they will also be considered acceptable. However, if two types from differing groups are compared, an error occurs. This is to prevent the user from doing something silly like trying to compare a JPG to an AVI. Mistakes like this can happen, and just end up with the user launching multiple failed compare-sessions which serve no purpose and waste time. The more advanced 3rd-party comparers (such as Beyond Compare) can handle such things as all types of photographs (on a pictoral level, not just as binary objects) and can even compare .reg files to the live registry before you merge them, so a certain flexibility is built in when passing filetypes in general.

The same idea applies to folders - CompareHandler will consider any attempt to compare a folder to a file as an error (obviously) unless that file is a "folder-type", such as a known archive-type. Obviously not all comparers are able to breakdown archives automatically, but most should be able to handle the usual archive types of: *.rar, *.zip, *.7z, *.chm, *.gz, *.bz?, *.jar, *.cab. These will all be considered as permissible de-facto folders when selected against a folder path. If that list does not include an archive-type which you want to force to be recognised, just create a new group called "archives" within x2 and add your extensions. The ones listed here are already defined within CompareHandler so you don't need to worry about them.

If, however, you don't like this sort of policing, and want to be free to make your own silly mistakes, you can always switch filetype matching off (or even prevent any error reporting at all) by using the menu/CLI options /NoError and /NoExt. Personally I find it handy to have such things monitored, and only ever need to override a mis-match error very rarely (once all the filetypes used regularly within x2 are registered).

I think that about covers it - in case anyone looks at the source-code and is flabberghasted to discover that enforcing four simple rules and adding a few options somehow requires 850 lines of code, they should note that there are about a hundred intermixed If/Then conditionals (based on active-pane, location of selections, etc) which all need to be handled correctly and in the correct order. Hence the reason this is my bête noire - it's such a simple thing, but the task has proven greater than the protagonist each time, and I regularly (admittedly, five times now) have fallen to my knees weeping at the pallid attempt my imagination allowed. Perhaps this time I will have gotten it "right" - I can but beg forgiveness if I have not. :shrug:

As usual, questions, comments, critiques, requests - all are welcome. I would like the thank the forum member Snakebyte for introducing me to Beyond Compare a few years ago, it rather quickly become my most oft-used programme after x2, firing up multiple times a day thus inspiring this utility. If curses could be considered a gratitude, I am Caliban to Snakebyte's Prospero, and needs-must I forever curse thee most loud. :wink:
Last edited by Kilmatead on 2017 Mar 15, 19:48, edited 2 times in total.

User avatar
Silver Member
Silver Member
Posts: 303
Joined: 2002 Mar 19, 08:54
Location: UK

Re: Driving 3rd-Party Comparisons in x2 (A Paradigmatic Util

Post by vserghi » 2014 Mar 16, 19:35

Saw this and thought this could be handy. I have used all four of those utilities and my current preference is WinMerge. As I did not know what a paradigmatic utility was, I stepped forward with guns off safety at least.

Not wishing to belittle your work, I can understand somewhat, continuous work on a utility in trying to perfect it, I can't see how it betters the existing capabilities of x2.

I have WinMerge set up to compare two files or folders right now in each pane. I can compare two items via the context menu in an active pane. When you select any specific external command, you automatically preselect the files or folders that you want to perform the task on already.

I'm not sure where your utility betters what is there already.

Platinum Member
Platinum Member
Posts: 4569
Joined: 2008 Sep 30, 06:52
Location: Dublin

Re: Driving 3rd-Party Comparisons in x2 (A Paradigmatic Util

Post by Kilmatead » 2014 Mar 16, 20:27

The distinction is subtle, I'll grant you. Primarily where it comes into play is selecting single items in both panes at the same time (or 1 in 1, two in 'tother), or without any selections at all and simply "assuming" the actual pane-paths themselves, without the user needing to fiddle with iterating single-selection based context menus and going "back" a level just to get the path of any given current pane that you're already looking at.

For example, one of the tasks I seem to be doing endlessly, is to be mounting image-backups in x2 (Macrium Reflect archives) to compare to the "state" of the current system, so I can gauge precisely which objects (including offline registry contents) have changed/removed (system-wide) since the last backup. This employs a complex set of pulleys and strings where x2 "auto" activates the mirror browsing/scrolling modes of a "live" C:\ root and an old image upon mounting (occasionally concurrent images). Introducing that to Beyond Compare (the only utility which doesn't crash when comparing live images of millions of objects browsing realtime from the root) necessitated a more structured approach to using the "directly visible" panes in x2, rather than going to the parent and selecting the child as a right-click afterthought.

Atop that, not all of the listed utilities include their own context-menu handlers, and those that do can be "fiddly". For example Beyond Compare employs a simple enough system of "Select Left Object" which then changes to "Compare to Left Object" upon right-clicking another file - frustrating the idea of 3-way merging for text/folders, or even single selections of .REG files (where the utility needs to be launched, but there is no "opposing object" because it's the live registry itself) - or, for that matter, merely launching the utility "plain" to carve a bespoke session from scratch.

Thus, my approach was to simplify it all down (including the stuff the context menus actually do well enough) to a single button-launch which could easily encapsulate almost any combination of parameters from any source, at worst preserving the same conduit via x2 no matter which of the given utilities was actually being used.

Originally, I had played the usual game of trying to get a user-command to handle selections (even inactive pane selections) itself, but the sequence the arguments were submitted to the target could never be guaranteed and items on the "Left" in x2 could accidentally end up on the "Right" in the comparer, depending on which pane was active at any given time. So I rejected that approach.

I readily accept that most users familiar with 3rd-party comparisons have by now developed their own dynamic work pattern, but this is just my concerted stab at it. I chose a simple set of logical rules which would always be a "given" no matter what I was looking at, all the while being independent of the comparer in question - and I liked that idea - never a guarantee that anyone else would. :D

You could always try it for a few days to see if you find any subtleties otherwise overlooked at first glance (it's bloody complex yet simple on the surface)... then toss it away with nothing lost if it doesn't suit your karma. I generally work on the principle that 1 in every 4,251 people who read the thread actually bother to try the silly programmes I write anyway, so it amuses me to imagine the lonely souls who struggle in the darkness with maybe one in a million seeing the light before dying their horrible deaths, their names forever unbeknownst to me.


(I was the kid in school who always gave the loooonnnggg-winded answers to simple questions. :wink:)

Post Reply