Wie kann ich feststellen, ob bereits eine andere Instanz meines Programms läuft?
Wie kann ich feststellen, ob eine Instanz von meinem Programm ausgeführt wird?
Ich dachte, ich könnte dies mit einer Daten-Datei, aber es wäre nur unordentlich 🙁
Will ich tun, wie ich will nur 1 Instanz immer offen an einer Stelle.
InformationsquelleAutor der Frage Arthur | 2009-01-19
Du musst angemeldet sein, um einen Kommentar abzugeben.
Können Sie erstellen, Semaphore und Ausführung beenden (legen Sie den code in die *.dpr-Datei) aus und bringen Sie die Laufenden Anwendungen auf den Bildschirm.
BEARBEITEN (Hinzugefügt
RestoreWindow
- Methode):Den
aFormName
ist der name Ihrer wichtigsten form-Klasse in Ihrer Anwendung.InformationsquelleAutor der Antwort Drejc
Als Jon zunächst vorgeschlagen, Sie können versuchen, die Schaffung eines mutex. Rufen Sie
CreateMutex
. Wenn Sie einen nicht-null-handle zurück, dann rufen SieGetLastError
. Es wird Ihnen sagen, ob Sie die waren, die erstellt die mutex oder ob der mutex bereits geöffnet war, bevor (Error_Already_Exists
). Beachten Sie, dass es nicht zu erwerben Besitz des mutex. Der mutex ist nicht seiend verwendet für gegenseitigen Ausschluss. Es wird verwendet, weil es ist eine benannte kernel-Objekt. Ein Ereignis oder semaphore könnte auch funktionieren.Den mutex-Technik gibt Ihnen eine Boolesche Antwort: ja, es ist eine andere Instanz, oder Nein, gibt es nicht.
Sie wollen Häufig mehr wissen, als nur das. Zum Beispiel, möchten Sie vielleicht wissen, den Griff des anderen Instanz, die das Hauptfenster so kann man es sagen, zu der Vorder zu kommen, in den Ort deiner anderen Instanz. Das ist, wo die eine memory-mapped-Datei kann in handliches kommen; es können sich Informationen über die erste Instanz, so dass höhere Instanzen verweisen kann.
Vorsichtig sein bei der Auswahl der name des mutex. Lesen Sie die Dokumentation sorgfältig durch, und beachten Sie, dass einige Zeichen (wie z.B. backslash) sind nicht erlaubt in einigen OS-Versionen, aber sind für bestimmte Funktionen erforderlich sind, die in anderen OS-Versionen.
Erinnere mich auch an das problem von anderen Usern. Wenn Ihr Programm konnte ausgeführt werden, die über remote desktop oder fast user switching, dann könnte es anderen Benutzern, die bereits laufen, Ihr Programm, und Sie vielleicht nicht wirklich wollen, zu beschränken, den aktuellen Benutzer aus läuft Ihr Programm. In diesem Fall, nicht mit einem globalen Namen. Wenn Sie tun soll der Zugriff für alle Benutzer, dann stellen Sie sicher, dass das mutex-Objekt security Attribute sind, so dass jeder in der Lage zu öffnen, ein Griff. Mit einem null-Zeiger für die
lpSecurityAttributes
parameter nicht ausreichend für die; die "Standard-Sicherheits-Deskriptor", der MSDN erwähnt, gibt vollen Zugriff auf den aktuellen Benutzer und keinen Zugang zu anderen.Dürfen Sie Bearbeiten die DPR-Datei des Programms. Das ist in der Regel ein guter Ort, das zu tun diese Art der Sache. Wenn Sie warten, bis die
OnCreate
Fall, dass eine Ihrer Formen, dann ist dein Programm schon hat, ein bisschen Dynamik in Richtung normal läuft, so ist es ungeschickt, zu versuchen, das Programm zu beenden. Besser zu beenden, bevor zu viel UI-Arbeit geleistet worden. Zum Beispiel:Gibt es eine Frage, Wann schließen Sie das mutex-handle. Sie nicht haben, um es zu schließen. Wenn ein Prozess schließlich beendet wird (auch wenn es stürzt ab), wird das OS automatisch schließen Sie alle hervorragend verarbeitet, und wenn es keine mehr Griffe öffnen, wird die mutex-Objekt wird zerstört werden (so dass eine weitere Instanz des Programms zu starten, und halte sich an die erste Instanz).
Vielleicht möchten Sie aber schließen Sie den Griff sowieso. Angenommen, Sie entschied sich für die Implementierung der
SendDataToPreviousInstance
Funktion, die ich erwähnt in dem code. Wenn Sie wollen bekommen Sie Lust, dann könnte man den Fall berücksichtigt, dass die vorherigen Instanz bereits heruntergefahren und ist nicht in der Lage zu akzeptieren, die neuen Daten. Dann wirst du nicht wirklich wollen, um zu schließen Sie die zweite Instanz. Die erste Instanz konnte in der Nähe der mutex-handle, sobald es weiß, dass es Herunterfahren, die im Effekt zu einer "lame duck" - Instanz. Die zweite Instanz wird versuchen, den mutex-handle, ist erfolgreich, und sieht sich die erste richtige Instanz. Die Vorherige Instanz schließen, ununterbrochen. VerwendenCloseHandle
schließen, um den mutex; rufen Sie es von Ihrem Haupt-formOnClose
event-handler, oder wo auch immer Sie Sie nennenApplication.Terminate
zum Beispiel.InformationsquelleAutor der Antwort Rob Kennedy
Der all-mächtigen JVCL hat eine Komponente für diesen Zweck. Siehe "TJvAppInstances".
InformationsquelleAutor der Antwort utku_karatas
Erstellen Sie eine system mutex.
Habe ich nicht den Delphi-code, aber hier ist C++ - code:
InformationsquelleAutor der Antwort Kluge
Die normale Lösung ist das erstellen einer benannt, system-wide mutex.
EDIT:
Ich noch keinen code, da ich nicht weiß Delphi. Ich kann C# - code, falls das hilfreich wäre, wenn.
InformationsquelleAutor der Antwort Jon Skeet
Möchte ich hinzufügen, zeigen Sie auf die ausgezeichnete Antwort von Rob Kennedy (abgesehen von der Tatsache, dass es am besten wäre, um eine Funktion aus seinem code nicht kopiert, sondern alles in der DPR-Datei. Sie benötigen nur zwei Parameter, den Namen des mutex und ein boolean, ob die mutext sollte pro-Benutzer-oder system-wide).
Die Antwort nicht geben viel Rücksicht auf die Benennung des mutex. Wenn Sie erwarten, dass Ihr Programm installiert werden, über Inno-Setup (und vielleicht andere setup-tools zu) wählen Sie den Namen sorgfältig, als mutex verwendet werden können, um das setup-Programm prüfen, ob die Anwendung derzeit ausgeführt wird, und warnt den Benutzer, dass Sie schließen Sie alle Instanzen der Anwendung. Wenn Sie eine Instanz des Programms pro Benutzer müssen Sie möglicherweise erstellen Sie eine zweite systemweiten mutex zu, wie das setup müssen keine Laufenden Instanzen der Anwendung an alle, um in der Lage sein, Dateien zu ersetzen. Der name ist, der verwendet werden für die Synchronisierung mit einem InnoSetup-installer muss hart kodiert werden.
InformationsquelleAutor der Antwort mghie
Ich würde sagen, dass es gibt mehrere verschiedene Strategien, die Sie einsetzen können. Aber die einfachste (und nicht Plattform-spezifisch) ist die, die Sie selbst vorgeschlagen haben, nämlich beim start des Programms überprüfen, um zu sehen, ob es eine lock-Datei erstellt in einer Gruppe, einem bestimmten Ort. Wenn diese lock-Datei existiert, dann wird eine andere Instanz wird bereits ausgeführt, wenn es nicht vorhanden ist, dann gibt es nicht eine andere Instanz ausgeführt. Wenn Ihr Programm beendet wird, löschen Sie die lock-Datei.
Jedoch der Einsatz dieser Strategie haben Sie ein weiteres problem, was passiert, wenn dein Programm abstürzt? Die lock-Datei noch bleibt, und in diesem speziellen Fall behandelt werden müssen.
Andere Strategie ist die systemweiten mutex-Lösung, in denen Sie sich Ihre Präsenz innerhalb des Betriebssystems (oder es ist auch plausibel, dass dies geschieht automatisch). Wenn eine zweite Instanz dann versucht zu starten, es wird überprüft, ob bereits ein Prozess aktiv mit einer bestimmten ID. Wenn es bereits vorhanden ist, wird der zweite Prozess entscheidet, nicht zu starten, und Optional bringt der erste Prozess " - Fenster den Fokus hat (wenn der Prozess in Frage, besitzt ein Fenster, das ist).
Doch diese Strategie ist Plattform-spezifisch ist, und die Umsetzung unterscheiden sich von Plattform zu Plattform.
InformationsquelleAutor der Antwort jimka
Können Sie einfach verwenden Sie windows-api-Funktion FindWindow. Im delphi-Klassen-name des Fensters ist das gleiche wie class-Namen, Sie können neu Klasse Namen durch überschreiben der CreateParams-Funktion. Um zu überprüfen, ob Fenster vorhanden ist, fügen Sie code vor der main-Fenster erstellt wird , vor der Anwendung.Initialisieren;
InformationsquelleAutor der Antwort Edin Omeragic
Steuerung der Anzahl der Anwendungs-Instanzen:
http://delphi.about.com/od/windowsshellapi/l/aa100703a.htm
InformationsquelleAutor der Antwort g2mk
Sehen diesem Gerät (mit CreateMutex): UiApp
Zusätzlich auf dieser Seite, Sie können Lesen die vor-und Nachteile in dieser Arbeit mit verschiedenen Methoden (mutex, FindWindows,...).
Dieser Einheit haben die Lösung aktivieren Sie die Vorherige Instanz der Anwendung, wenn diese erkannt wird.
Grüsse und Entschuldigung für mein schlechtes Englisch.
Neftalí -Germán Estévez-
InformationsquelleAutor der Antwort Germán Estévez -Neftalí-
In der Vergangenheit, ich habe eine Steckdose, um zu verhindern, dass mehrere Instanzen gleichzeitig ausgeführt werden. Wenn die Buchse in Benutzung ist, nicht weiterhin das Programm, wenn es verfügbar ist, lassen alles laufen wie gewohnt.
InformationsquelleAutor der Antwort ahanson