Windows-Utility: Dateien vergleichen
Die Beispieldateien zur Script-Komponente VTOOL enthalten neuere Scripte zur Durchführung eines Dateivergleichs (filecompare.vbs und filecompare2.vbs).
Für doppelte Dateien auf der Festplatte sollte es immer einen guten Grund geben, z.B. die Notwendigkeit von Arbeits- oder Sicherungskopien. Mitunter stößt man jedoch auf Dateien, bei denen nicht klar ist, ob sie wirklich identisch sind. Dann stimmen zwar die angezeigten Dateigrößen überein, aber es besteht die Möglichkeit, dass sich die Dateiihalte doch irgendwie unterscheiden. Man müsste also einfach einen inhaltlichen Vergleich der Dateien durchführen.
Für solche Zwecke gibt es etliche Programme, eines davon befindet sich auf jedem Windows-System: FC (File Compare, fc.exe). Dabei handelt es sich um ein einfaches Kommandozeilen-Programm, das es auch schon zu DOS-Zeiten gab. (In den Dateieigenschaften wird es denn auch als »DOS 5 File Compare Utility« beschrieben. 1 Das Programm läuft unter Windows folglich in einem Konsolenfenster.
Das ist aber wirklich kein Problem, denn in den meisten Fällen will man ja einfach nur wissen, ob Unterschiede zwischen zwei Dateien bestehen. Diese Aufgabe erfüllt das Programm sehr gut. Nur bei besonders großen Dateien, z.B. CD-Images, muss man einige Geduld mitbringen (oder sich nach einer anderen Lösung umsehen). 2 Die Schwierigkeit liegt mehr beim Programmaufruf, denn die beiden Dateinamen müssen dabei vollständig als Programmparameter angegeben werden. Das ist natürlich sehr umständlich und fehlerträchtig.
Es ist aber ziemlich einfach, eine Brücke zwischen »schwarzer Konsole« und visueller Dateiauswahl zu schlagen, da Windows die entsprechenden Mittel bereitstellt. Über den Windows Script Host (WSH) lässt sich der Einsatz von FC leicht komfortabler gestalten. In diesem Fall verwenden wir Visual Basic Script (VBS) um die beiden Dateien bequem auszuwählen und dann in einem Programmaufruf an FC zu übergeben.
Der Hauptteil des kleinen VBS-Programms befasst sich dementsprechend fast nur mit der Logik der Dateibestimmung. Zunächst wird die Möglichkeit vorgesehen, dass ein Dateiname schon direkt an das Programm übermittelt wurde. (Wie das geschehen kann, erkläre ich später noch.) Ist das nicht der Fall, dann wird der Standarddialog von Windows für das Öffnen einer Datei bemüht. Und dies dann ebenso für den zweiten Dateinamen.
' fcompare zwei Dateien via FC vergleichen ' ' © 2010, 2011 E. Riedel (ERCC) ' Dim dir1, file1, file2 If Wscript.Arguments.Count Then file1 = Wscript.Arguments(0) Else file1 = GetFileName(1, "") End If If file1 = "" Then MsgBox "Keine Datei ausgewählt!",,"fcompare: Error" Else dir1 = GetFilePath(file1) file2 = GetFileName(2, dir1) If file2 = "" Then MsgBox "Keine 2. Datei ausgewählt!",,"fcompare: Error" Else Compare file1, file2 End If End If
Die Dateiauswahl ist natürlich als Funktion ausgegliedert. Dabei wird auch der Fall vorgesehen, dass der Aufruf des Standarddialogs aus irgendwelchen Gründen misslingt (s.u.!). Als Alternative wird dann ein schlichtes Eingabefeld angeboten. Freilich ginge damit der Komfort verloren, aber das ist immer noch besser als ein Fehler im Programmablauf.
Function GetFileName(nr, path) ' Version 1 Dim dlg, f, ws On Error Resume Next Set dlg = CreateObject("MSComDlg.CommonDialog") ' Dateiauswahl-Dialog If Err Then Err.Clear f = InputBox("Sorry, Common-Dialog nicht ausführbar!" & vbLF & _ "Bitte " & nr & ". Dateinamen eingeben: ", "fcompare: Dateien vergleichen") Else If path = "" Then Set ws = WScript.CreateObject("WScript.Shell") If Err Then Err.Clear f = "" Else f = ws.CurrentDirectory End If Else f = path End If dlg.Filter = "Alle Dateien (*.*)|*.*|" dlg.FilterIndex = 1 dlg.MaxFileSize = 256 dlg.CancelError = False dlg.DialogTitle = "fcompare: Dateiauswahl " & nr dlg.InitDir = f dlg.ShowOpen f = dlg.FileName End If GetFileName = f End Function
Damit die zweite Datei nicht irgendwo, sondern sozusagen in der Nähe der ersten gesucht wird, erhält die Auswahlfunktion beim zweiten Mal den Dateipfad der ersten Datei als Vorgabe. Dieser Dateipfad wird durch eine kleine Extrafunktion bestimmt.
Function GetFilePath(filespec) Dim fso, f On Error Resume Next Set fso = CreateObject("Scripting.FileSystemObject") Set f = fso.GetFile(filespec) GetFilePath = f.Path End Function
Zu guter Letzt rufen wir (via Kommandozeileninterpreter cmd) das Programm fc auf, mit den beiden Dateibezeichnungen als Parametern. Die Befehlszeile erscheint ein wenig unübersichtlich, weil man auch diverse Leerzeichen und zusätzlich notwendige Anführungszeichen codieren muss.
Sub Compare(file1, file2) Dim ws, s, c On Error Resume Next Set ws = WScript.CreateObject("WScript.Shell") If Err Then MsgBox "Sorry, Shell konnte nicht aufgerufen werden!",,"fcompare: Error" Else s = Chr(34) c = "CMD.EXE /K " & s & "fc /B " & s & file1 & s & " " & s & file2 & s & s ws.Run c End If End Sub
Die Funktion GetFileName ist nun entsprechend abzuändern. Die folgende Version berücksichtigt beide Komponenten. Der übrige Programmtext ändert sich nicht.
Function GetFileName(nr, path) ' Version 2 Dim dlg, f, ws, x On Error Resume Next Set dlg = CreateObject("MSComDlg.CommonDialog") ' Dateiauswahl-Dialog If Err Then Err.Clear x = True Set dlg = CreateObject("FileDlg.FileSelection") ' alternativ If Err Then Err.Clear f = InputBox("Sorry, kein Dateiauswahl-Dialog ausführbar!" & vbLF & _ "Bitte " & nr & ". Dateinamen eingeben: ", "fcompare: Dateien vergleichen") GetFileName = f Exit Function End If End If If path = "" Then Set ws = WScript.CreateObject("WScript.Shell") If Err Then Err.Clear f = "" Else f = ws.CurrentDirectory End If Else f = path End If dlg.DialogTitle = "fcompare: Dateiauswahl " & nr dlg.InitDir = f If Not x Then dlg.Filter = "Alle Dateien (*.*)|*.*|" dlg.FilterIndex = 1 dlg.MaxFileSize = 256 dlg.CancelError = False dlg.ShowOpen Else dlg.ShowDialog End If f = dlg.FileName GetFileName = f End Function
In dieser Form ist das Programm fcompare.vbs auch schon benutzbar. Es kann im Windows-Explorer oder durch Befehlseingabe aufgerufen werden.
Allerdings wird die Programmbenutzung deutlich komfortabler, wenn durch den Explorer auch gleich die erste Datei übergeben wird, d.h. Dateiwahl und Programmaufruf in einem Schritt erfolgen. Hierfür bieten sich zwei Wege:
- Das Explorer-Kontextmenü für eine Datei kann um einen neuen Eintrag mit dem entsprechenden Programmaufruf ergänzt werden. Dies erfordert Veränderungen an der Windows-Registratur (Registry).
- Der Eintrag (bzw. das Submenü) Senden an im Explorer-Kontextmenü kann um den Programmaufruf ergänzt werden. Dies erfordert eine Programm-Verknüpfung im SendTo-Verzeichnis.
An dieser Stelle wird der zweite Weg vorgeschlagen. Er ist für Anwender ein wenig einfacher durchzuführen (und auch ein Stück weit risikoloser). Allerdings erledigt das hier angebotene Installationsprogramm die weiteren Schritte automatisch. 3 Insoweit dient die folgende Beschreibung vor allem dem besseren Verständnis.
Zunächst ist das Programm fcompare.vbs an einem geeigneten Ort zu speichern. Die Installationsvorgabe lautet auf das Programmverzeichnis FCOMP, Sie können aber auch ein anderes Verzeichnis bestimmen.
Sodann ist eine Verknüpfung im Ordner SendTo zu erstellen. Der befindet sich in Windows 2000/XP unterhalb des Verzeichnisses
\Dokumente und Einstellungen\Benutzername\
(also bspw.: »C:\Dokumente und Einstellungen\Claudia\SendTo«).
Ab Windows Vista ist das SendTo-Verzeichnis jedoch in Ordner-Untiefen verlagert worden, der Pfad auf dem Systemlaufwerk lautet nun:
\Users\Benutzername\AppData\Roaming\Microsoft\Windows\SendTo
Der einfachste Weg führt über die Eingabe des Kürzels shell:sendto in der Navigationsleiste des Windows Explorers, der damit direkt in das SendTo-Verzeichnis des aktuellen Benutzers wechselt.
Die Verknüpfung zu einem Programm lässt sich im Explorer einfach mit der Maus erstellen: Man klickt mit der rechten Maustaste auf die Programmdatei, hält die Taste gedrückt und zieht die Datei in das Zielverzeichnis. Wenn man nun die Taste loslässt, erscheint ein Kontextmenü, in dem die Option Verknüpfung(en) hier erstellen auszuwählen ist.
(Alternativ kann man auch erst die Verknüpfung erzeugen und diese dann in das Zielverzeichnis verschieben. Das lässt sich sogar ohne Mausakrobatik über Menüoptionen erreichen.)
Am Ende dieser Abfolge ist im SendTo-Verzeichnis eine Programmdatei-Verknüpfung entstanden, die man ggfs. im nächsten Schritt noch auf sinnvolle Weise umbenennen sollte. Um ein Beispiel zu geben:
Lohn der Mühe ist dann ein hübscher neuer Menüeintrag im Explorer …
… durch den direkt die erste Datei für den Vergleich mit unserem Programm fcompare.vbs ausgewählt werden kann.
Der Clou ist dabei natürlich, dass fcompare.vbs selbst auch einen Aufrufparameter auswertet, wie ja anfangs erwähnt. Und diesen Parameter (Dateinamen) erhält das Programm hier über den Explorer.
1) Neuerdings auch etwas unsinnig (bzw. schlecht übersetzt) als »Programm zum Vergleichen von DOS 5-Dateien«.
2) Übrigens lässt sich der Programmlauf von FC (wie bei den meisten Konsolenprogrammen) durch die Tastenkombination Strg+c abbrechen.
3) Das Installationsprogramm setup_fcmp.exe richtet ein Programmverzeichnis FCOMP (Vorgabe) mit den Dateien fcompare.vbs und uninstall.exe ein, für die es auch Startmenü-Einträge unter DATEIVERGLEICH erzeugt. Die Dialogkomponente filedlg.dll wird im Ordner für »Gemeinsame Dateien« in einem eigenen Verzeichnis FFDLG gespeichert. Das Installationsprogramm registriert diese Komponente für Windows und erzeugt die oben beschriebene SendTo-Verknüpfung. Mit dem Programm uninstall.exe (auch erreichbar über die Systemsteuerung) kann die gesamte Installation gelöscht werden.
setup_fcmp.exe
ausführbares Setup-Programm zur Installation von fcompare.vbs und FILEDLG.DLL
dateivergleich.zipenthält in gepackter Form nur das Programm fcompare.vbs und diesen Artikel als CHM-Datei. (Für Anwender, die die Installation selbst durchführen wollen und das COM-Modul FILEDLG.DLL nicht brauchen.)