I freely confess to having made almost no attempt to make this code highly portable. It is really intended as an example for others to modify to suit and hopefully improve. In particular, the way I decide what to compare under what circumstances may well be different to the logic others would instinctively choose.
In some of my other test scripts I use a global variable to switch debugging on/off but I overlooked that when I knocked this script up and was too idle to go back and change it afterwards.
Thanks for pointing this out. I have modified my VBScript version to deal with libraries.
@language vbscript
option explicit
' "Smart" front end to Beyond Compare
' (Re)Written by AussieBoykie in VBScript because it is more familiar to the author! 8-)
' Handles very long paths as best possible
' Logic for what is actually compared is articulated in comments in the code. See below..
Function OnClick(ByRef ClickData)
Dim dbg
Dim cdf
Dim fsu
Dim sPath
Dim sPathIsLib
Dim dPath
Dim dPathIsLib
Dim nodest
Dim src
Dim tgt
Dim l
Dim r
Dim n
Dim pair
Dim cd
Dim BCBeta
Dim BCVer
Dim BCCmd
Dim BCArgs
Dim cmdstring
Const lib = "lib://"
Const vbQuote = """"
'Const dbg = TRUE ' Switch to FALSE to disable or TRUE to enable debug output
Set cdf = ClickData.func
dbg = cdf.Command.IsSet("$lst:dbg")
Set fsu = DOpus.FSUtil
' Test the global variable BCBeta to decide whether to use Beyond Compare 3 (stable) or 4 (beta)
' Edit the BCCmd = statement below to reflect the correct path to the BC executable on your system
BCBeta = cdf.Command.IsSet("$glob:BCBeta")
if BCBeta then BCVer = 4 else BCVer = 3
BCCmd = "/homeroot\utilities\bc" & BCVer & "\bcompare.exe"
if dbg then DOpus.Output "BCCmd: " & BCCmd
Set src = cdf.sourcetab
sPath = src.path
sPathIsLib = lcase(Left(sPath,6)) = lib
if sPathIsLib then sPath = fsu.Resolve(sPath)
nodest = cdf.desttab = 0
if dbg then DOpus.Output "nodest: " & nodest
if nodest then
Set tgt = src
dPath = sPath
else
Set tgt = cdf.desttab
dPath = tgt.path
dPathIsLib = lcase(Left(dPath,6)) = lib
if dPathIsLib then dPath = fsu.Resolve(dPath)
end if
n = 1
if len(dPath) > len(sPath) and not dPathIsLib then
cd = dPath
if not right(dPath,1)="\" then n = 2
elseif not sPathIsLib then
cd = sPath
if not right(sPath,1)="\" then n = 2
else
cd = ""
n=0
end if
if dbg then DOpus.Output "Sourcetab: " & sPathIsLib & " - " & sPath
if dbg then DOpus.Output "Desttab: " & dPathIsLib & " - " & dPath
' The final BC command string is of the form <some path>\bcompare.exe <spec1> <spec2>
' The combined length of <spec1> and <spec2> can cause problems if one or other or both is very long
' In an attempt to avoid problems we will change directory before executing the BC command
' The target directory will be either <spec1> or <spec2>, whichever is longest
' The target name can then be specified without its path - e.g. some.txt instead of C:\SomeLongPath\some.txt
pair = false
if src.selected_files.count = 2 then
if sPathIsLib then
l = fsu.Resolve(src.selected_files(0))
r = fsu.Resolve(src.selected_files(1))
else
l = mid(src.selected_files(0),len(sPath)+n)
r = mid(src.selected_files(1),len(sPath)+n)
end if
pair = true
if dbg then DOpus.Output "Left File: " & l
if dbg then DOpus.Output "Right File: " & r
elseif src.selected_dirs.count = 2 then
if sPathIsLib then
l = fsu.Resolve(src.selected_dirs(0))
r = fsu.Resolve(src.selected_dirs(1))
else
l = mid(src.selected_dirs(0),len(sPath)+n)
r = mid(src.selected_dirs(1),len(sPath)+n)
end if
pair = true
if dbg then DOpus.Output "Left Folder: " & l
if dbg then DOpus.Output "Right Folder: " & r
end if
' If SOURCE and DEST are the same then...
' If exactly two files are selected (whether or not folders are also selected)
' or exactly two folders are selected (whether or not files are also selected)
' then execute a compare, otherwise just bring up the Beyond Compare main menu
if sPath = dPath then ' Source only
if pair then
BCArgs = vbQuote & l & vbQuote & " " & vbQuote & r & vbQuote
else
BCArgs = ""
end if
' If SOURCE and DEST are different then...
' If exactly one SOURCE file and one DEST file are selected (whether or not folders are also selected)
' or exactly one SOURCE folder and one DEST folder are selected (whether or not files are also selected)
' then execute a compare, otherwise...
' if a pair of files or a pair of folders is selected in SOURCE then execute a compare, otherwise
' compare SOURCE and DEST folders
else
if src.selected_files.count = 1 and tgt.selected_files.count = 1 then
if cd = sPath then
l = mid(src.selected_files(0),len(sPath)+n)
r = fsu.Resolve(tgt.selected_files(0))
elseif cd = dPath then
l = fsu.Resolve(src.selected_files(0))
r = mid(tgt.selected_files(0),len(dPath)+n)
else
l = fsu.Resolve(src.selected_files(0))
r = fsu.Resolve(tgt.selected_files(0))
end if
BCArgs = vbQuote & l & vbQuote & " " & vbQuote & r & vbQuote
elseif src.selected_dirs.count = 1 and tgt.selected_dirs.count = 1 then
if cd = sPath then
l = mid(src.selected_dirs(0),len(sPath)+n)
r = fsu.Resolve(tgt.selected_dirs(0))
elseif cd = dPath then
l = fsu.Resolve(src.selected_dirs(0))
r = mid(tgt.selected_dirs(0),len(dPath)+n)
else
l = fsu.Resolve(src.selected_dirs(0))
r = fsu.Resolve(tgt.selected_dirs(0))
end if
BCArgs = vbQuote & l & vbQuote & " " & vbQuote & r & vbQuote
elseif pair then
BCArgs = vbQuote & l & vbQuote & " " & vbQuote & r & vbQuote
else
l = sPath
r = dPath
BCArgs = vbQuote & l & vbQuote & " " & vbQuote & r & vbQuote
end if
end if
if lcase(l) = lib then
if dbg then DOpus.Output "l = " & l & " : r = " & StripPath(r)
eMsg "Unable to compare " & l & " with " & StripPath(r)
elseif lcase(r) = lib then
if dbg then DOpus.Output "r = " & r & " : l = " & StripPath(l)
eMsg "Unable to compare " & StripPath(l) & " with " & r
else
cmdstring = vbQuote & BCCmd & vbQuote & " " & BCArgs
if dbg then DOpus.Output cmdstring
With cdf.Command
.deselect = FALSE
if not cd = "" then .addline "cd " & spath
.addline cmdstring
.run
End With
end if
End Function
Sub eMsg(msg)
' Display a supplied error message
Dim objDlg
Dim result
Set objDlg = Dopus.Dlg
With objDlg
.title = "Fatal Error"
.buttons = "Quit"
.message = msg
result = .show
End With
End Sub
Function StripPath(filespec)
Dim s
Dim n
s = StrReverse(filespec)
n = InStr(1,s,"\")
if n > 0 then
StripPath = StrReverse(Left(s,n-1))
else
StripPath = filespec
end if
End Function
I have the executable of my Beyond Compare 3 in E:\BACKUP\New backup\Program\Beyond Compare 3\BCompare.exe. How should I edit the BCCmd according to my mentioned path?
Ya, I have already changed the BCCmd = statement below the "if BCBeta then BCVer = 4 else BCVer = 3" to "BCCmd = "E:\BACKUP\New backup\Program\Beyond Compare 3\BCompare" but I can only compare two items in a same pane. I thought this script can be used to compare items in different pane as well but if I do that, it will only open the Beyond Compare's Home. That is why I am asking. Could you confirm if this is a normal behavior or there is a missing step that I did?
As I recall it should work in a DUAL pane as follows:
If 2 files are selected in SOURCE pane, compare them.
If 2 folders are selected in SOURCE pane, compare them.
If 1 file is selected in SOURCE and 1 file in DEST then compare them.
If 1 folder is selected in SOURCE and 1 folder in DEST then compare them.
Otherwise compare SOURCE and DEST folders.
And if there is no DUAL pane:
If 2 files are selected in SOURCE pane, compare them.
If 2 folders are selected in SOURCE pane, compare them.
Otherwise open Beyond Compare main menu
I am in the process of testing a simpler and more efficient V2 which I expect to post later today.
Version 2 is attached as a ZIP. To install, extract Beyond Compare.vbs from the zip and copy this file into the /dopusdata\Script AddIns folder. You should then edit the script (via Preferences may be easiest) to point to the correct location of BCompare.exe on your system.
Hi AB, as you have converted this in to a script package, you could leverage the script configuration, this would mean that users don't need to edit the script to set the path.
In the init you would add something like this
Thanks wowbagger. Until you pointed it out I had not picked up on the ability to manage user supplied configuration variables. This is a neat way of doing things. I will post updated code and instructions shortly and link from the original post.
Yep it is very handy indeed. As the user wont need to edit the script you can rename the zip to ops, then they wont need to extract the vb file after downloading. Also if you use an ops file you can include icons with the script. This is nice because it means that you can provide a sample button with an icon without pulling that icon from the bcompare exe.
I have done up a sample, adding the bcompare icons to the zip you provided. Beyond Compare.osp (6.92 KB)
Version 2.1 is attached as an Opus Script Package. To install, copy the OSP file into the /dopusdata\Script AddIns folder. You should then configure the script via Preferences to point to the correct location of BCompare.exe on your system. Once installed you simply execute the $BC command to execute Beyond Compare. The "smart" compare logic is as described in an earlier post in this thread.
Note that the OSP includes Beyond Compare icons (once again, thanks to wowbagger) which can be used on any button you create to execute $BC.
' v2 = simpler, cleaner rewrite
' v2.1 add user configurable path to BCompare.exe via Preferences dialog
' (thanks to wowbagger for the suggestion)
' use fsu.resolve consistently to fully resolve paths
To install, copy the OSP file into the /dopusdata\Script AddIns folder (and delete any earlier versions). You should configure the script via Preferences to point to the correct location of BCompare.exe on your system. Once installed you simply run the $BC command to execute Beyond Compare. The "smart" compare logic is as described in an earlier post in this thread.