ERCC (http://eriedel.info)

Windows-Utility: Dateien vergleichen


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.


Abb.: Testanwendung FC im Windows-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
Nun gibt es jedoch bei dieser kleinen Programmlösung leider eine bedeutsame Einschränkung. Zwar ist der Standarddialog zur Dateiauswahl in jedem Windows enthalten (comdlg32.dll). Das gilt aber nicht für eine spezielle Zusatzdatei von Microsoft (comdlg32.ocx), die es erst ermöglicht, den Dialog in der gezeigten Weise zu verwenden. Da die Weitergabe dieser Datei gewissen Lizenzbedingungen unterliegt (auch für Programmierer), wird hier noch eine selbst entwickelte Ersatzkomponente angeboten (filedlg.dll, technische Beschreibung hier).

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:

  1. 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).

  2. 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:


Abb.: SendTo-Verzeichnis im Explorer


Lohn der Mühe ist dann ein hübscher neuer Menüeintrag im Explorer …


Abb.: erweitertes Kontextmenü

… 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.

 

Als Download sind folgende Dateien verfügbar:

 setup_fcmp.exe

ausführbares Setup-Programm zur Installation von fcompare.vbs und FILEDLG.DLL

 dateivergleich.zip

enthä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.)

http://eriedel.info/info/fc/dateivergleich.html


ERCC (http://eriedel.info)  03/2010 - 04/2011   © Erhard Riedel Computer Consulting (ERCC)


Link zur ERCC-Hauptseite   Link zur Info-Übersicht