Announcement

Collapse
No announcement yet.

Anwendung zweimal starten

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Anwendung zweimal starten

    Hallo Herr Kosch,

    Sie haben mir schon einmal mit Ihrem super Know-How geholfen, so daß ich mich ganz frech wieder an Sie wende.

    Ich möchte verhindern, daß mein Programm zweimal gestartet werden kann. Sprich, es soll beim zweiten Start die bereits vorhandene Instanz des Programms aktiviert werden.
    Unter "Backup 1999" habe ich die Diskussion "Verhindern, daß Anwendung 2 mal gestartet wird" gefunden, aber es geht da um ein Login-Fenster, das ich bei meinem Programm aber nicht habe.
    Ich denke, daß ich mit Botschaften das Problem lösen kann. Nur fehlt mir da noch das genaue Wissen dafür. Und aus der Online-Hilfe "Botschaftsbehandlungsroutinen" werde ich nicht so recht schlau.
    Können Sie mir weiterhelfen?
    Danke im voraus.

    Grüße, Reimund

    P.S. Wenn Sie mich jetzt wieder an Ihr Buch verweisen, wird es glaube ich langsam Zeit, daß ich es mir zulege. :-)

  • #2
    Hallo,

    in der Tat sind für diese Aufgabe in meinem Buch <i>Delphi Win32-Lösungen</i> gleich mehrere Beispielprojekte zu finden ;-)

    Zum einen könnte man über <b>FindWindowEx</b> nach einem Fenster mit der bekannten Beschriftung in der Titelzeile suchen. Wird dieses gefunden, wird es in den Vordergrund geholt und die neue Programminstanz erst gar nicht fertig initialisiert (Kapitel Services\Win9x\Service):
    <pre>
    begin
    hTargetWnd := FindWindowEx(0, 0, nil, c_FormTitel_Ex);
    if hTargetWnd <> 0
    then PostMessage(hTargetWnd, PM_ActivateApp, 111, 111)
    else begin
    Application.Initialize;
    Application.ShowMainForm := False; // Login-Formular
    Application.Title := 'Gateway';
    Application.CreateForm(TFormLogin, FormLogin);
    ShowWindow(Application.Handle, SW_HIDE); // Application-Window
    Application.Run;
    end;
    end.
    </pre>

    Zum anderen könnte man über <b>CreateFileMapping</b> ein eigenes Memory-Mapped-File anlegen und beim Aufruf prüfen, ob man dabei der Erste war (Kapitel DLL\MMFShare).

    Und zum dritten könnte man über <b>CreateMutex</b> das Betriebssystem mit dem Einrichten eines Sperrobjekts beauftragen und beim Start prüfen, ob man dabei der Erste war (Kapitel Threads\Threads)

    Comment


    • #3
      Hallo Herr Kosch,<br>
      sorry, daß ich mich jetzt erst wieder melde - war beruflich im Streß.<p>
      Habe Ihr Programmbeispiel bereits in einer älteren Diskussion gefunden und probiert. Aber irgendwie funktioniert es nicht.<br>
      Statt c_FormTitel_Ex verwende ich den Programmnamen aus Application.Exename (ohne Pfad und Extension) und statt PM_ActivateApp verwende ich WM_ActivateApp, da PM_ActivateApp vom Compiler moniert wird.<br>
      Den Fenstertitel vergebe ich erst in der FormCreate-Routine. Aber trotzdem wird bei FindWindowEx immer ein Wert <> 0 an hTargetWnd zugewiesen, sodaß das Programm auch beim ersten Mal überhaupt nicht hoch kommt.<br>
      Was mache ich falsch?<p>
      Grüße, Reimun

      Comment


      • #4
        Hi Andreas

        CreateMutex IST gefährlich. Ein Mutex ist Systemweit, schmiert die Anwendung ab, bleibt der Mutex im Speicher !! (entgegen M$ Dokumentationen). Demzufolge kann die Anwendung erst nach einem Systemneustart wieder gestartet werden. Andererseits werden Globale Atome geräumt. Es wäre also als Ersatz für ein Mutex ein globales String Atom sinnvoller !
        FileMappings werden dagegen ordentlich geräumt, auch wenn die Anwendung abschmiert (Task beenden etc.)

        Gruß Hage

        Comment


        • #5
          Hallo,

          die Botschaft <b>PM_ActivateApp</b> ist eine private Botschaft (PM = Private Message), die ich im reservierten Bereich für meine eigene Anwendung selbst definiert habe. Über diese Botschaft wird die bereits laufende Programminstanz darüber informiert, dass sie sich wieder in der Normaldarstellung anzeigen soll (wenn sie als Icon auf die Taskleiste abgelegt wurde).

          Der <b>FindWindowEx</b>-Aufruf sucht ein Fenster über die Fenstertitelzeilen-Beschriftung. Wird ein Fenster mit dem gleichen Text wie in der Konstanten c_FormTitel_Ex gefunden, geht das Programm davon aus, dass eine Programminstanz bereits läuft. Wichtig ist, dass hier die Schreibweise der Fensterbeschriftung exakt stimmen muss, der Anwendungsname ist unerheblich.

          Ein Mutex ist nur unter Windows 9x gefährlich (hier hat MS einige Situationen dokumentiert, die zum Einfrieren des Systems führen können), aber NT und 2000 sollten mit diesen Dingern stabil umgehen können. Im aktuellen Platform SDK verwendet Microsoft das folgende Versprechen "<i>The system closes the handle automatically when the process terminates. The mutex object is destroyed when its last handle has been closed.</i>".
          &#10

          Comment


          • #6
            Danke für den Hinweis.<p>
            P.S.: Habe Ihr Buch bestellt. Hoffe, dieses und weitere Probleme lösen zu können

            Comment

            Working...
            X