Wir haben ein Stück Code, dass verhindern soll, dass ein Programm zweimal gestartet werden kann.
Dieser basiert auf einem Mutex und einer Memory Mapped File, mit der man sich auch das Fenster-Handle einer bereits gestarteten Instanz besorgen kann.
Nun gelang es einem unserer Händler aber dennoch dieses Programm zweimal in einer Session zu starten und zwar auf folgendem Weg:
- Er startet die Software mit dem normalen Link auf dem Desktop, der durch das Installationsprogramm angelegt wurde.
- Er öffnen eine Console mit CMD.EXE und wechselt in das Verzeichnis, gibt den Programmnamen ein und das Programm startet erneut. 😮
Die Ursache ist war wie folgt:
- Der Mutex den wir intern verwendet haben nutzte den Dateinamen der EXE. Der Name des Mutex wird unter Anderem auch durch GetModuleFileName ermittelt.
- Der Dateiname der EXE, wenn sie als Verknüpfung gestartet wird ist „XYZ.exe“ (so wie die Datei auch auf der Festplatte heißt) und das liefert auch GetModuleFileName als Ergebnis.
- Der Dateiname, den GetModuleFileName liefert, wenn man das Programm aus CMD.EXE startest ist exakt so wie man es eintippt, also z.B. „xyz.exe“. Erstaunlich.
- Da der Mutex einen Namen case sensitiv behandelt (was ich nicht vermutet hätte und erst mit staunenden Augen nachgelesen habe), wurde das bereits gestartete Programm nicht erkannt und eine zweite Instanz gestartet.
Was schreiben wir uns also hinter die Löffel für die Zukunft:
a) GetModuleFileName liefert nicht den „exakten“ Dateinamen (obwohl ich es anders erwartet hätte)!
b) Mutexe sind case sensitiv wie auch Events (obwohl ich hier eine Behandlung wie bei einem Dateinamen erwartet habe)!
c) Manche Erwartungen trügen… 😉
Ist dir der Post nicht peinlich, Martin? 😉
Die offensichtliche Lösung ist doch, wirklich unverwechselbare, von *dir* kontrollierte Namen zu verwenden. Also einfach Guidgen anschmeißen und eine UUID generieren. Ich wundere mich wirklich, warum die Leute noch immer ihren Dateinamen für so wichtig halten…
@Andreas: Nein, es ist mir nicht peinlich. Warum auch?
Eigentliches Thema ist ja GetModulkeFileName und nciht mein Algorithmus. 😉
Ansonsten: Ich wollte dem Programmierer ersparen für das Modul eine eigene GUID erzeugen zu müssen.
Ließe sich Dein Code auch „austrixen“, wenn man die EXE für die zweite Instanz mit 8.3 Namen aufruft?
@Sascha: Nein. Wenn man die EXE mit dem 8.3 Namen startet wird der lange Dateiname verwendet.
Wie immer eine interessante Information.
Btw. läuft deine Seite nicht mit IPv6. Per Ping kommt eine Antwort, ausgeliefert wird aber nichts.
@Marc: Mein Provider ist Strato… iegentlich dachte ich müsste das automatisch funktionieren, wenn mein Provider es kann.
@Martin
Woran das liegt kann ich dir leider nicht sagen. Heise.de und andere IPv6 Seiten (meine eigene) gehen wunderbar. Nur dein Blog läßt sich nicht öffnen.