![]() |
Mutex und Programm nicht doppelt starten
Hallo...
ich verhindere auf folgende art und weise, das mein Programm nur einmal gestartet werden kann:
Delphi-Quellcode:
jetzt würde ich aber ganz gerne bei der laufenden Anwendung eine funktion aufrufen, weiß aber nicht wie ich das machen kann?
unit mutex;
interface implementation uses windows,Dialogs,sysutils,login; var mHandle: THandle; // Mutexhandle Initialization mHandle := CreateMutex(nil,True,'Stryyke Client'); if GetLastError = ERROR_ALREADY_EXISTS then begin Halt; end; finalization // ... und Schluß if mHandle <> 0 then CloseHandle(mHandle) end. Alse wenn mein Prog schon läuft, dann soll die Anwendung (dort wo jetzt Halt; steht) eine Funktion bei der laufenden instanz aufrufen. Kann man das irgendwie machen? |
Re: Mutex und Programm nicht doppelt starten
schickt ihr eine Message und rufe vom Message-Handler dann deine Funktion auf, also in etwa so:
Delphi-Quellcode:
Achtung: so ins unreine getippt, also Fehler nicht ausgeschlossen
h := 0;
repeat h := FindWindowEx(0,h,'TApplication',PCHar(Application.Title)); until h <> Application.Handle; if h <> 0 then begin Windows.SendMessage(h,SW_USER+4711,0,0); end; |
Re: Mutex und Programm nicht doppelt starten
ich kriegs nicht hin... mit deinem Code kommt es nicht vor, dass h <>0 ist.
dann dachte ich,´dass es so gehen müsste:
Delphi-Quellcode:
dann wollte ich die ApplicationEvents abfangen, dass habe ich so gemacht:
mHandle := CreateMutex(nil,True,'Stryyke Client');
if GetLastError = ERROR_ALREADY_EXISTS then begin ShowMessage('test'); Windows.SendMessage(mHandle,WM_USER,0,0); Halt; end;
Delphi-Quellcode:
procedure TLoginForm.ApplicationEvents1Message(var Msg: tagMSG;
var Handled: Boolean); begin if MSg.message = WM_USER then begin ShowMessage('Angekommen'); end; end; leider bekomme ich die ShowMessage('Angekommen'); nie zu sehen :cry: daraus schließe ich, dass das Windows.SendMessage(mHandle,WM_USER,0,0); nicht richtig geht oder? |
Re: Mutex und Programm nicht doppelt starten
Dein mHandle ist das Handle des Mutex, das geht natürlich nicht!
Was du brauchst ist das Handle auf die bereits laufende Instanz des Programmes, daher das Findwindow. Ich schrieb ja, das dort ein Fehler sein könnte. Such mal hier im Forum nach Mutex und Fenster nach vornebringen, dort gibt es funktionierende Lösungen. Edit: Habe eben in der Newsgruppe de.comp.language.delphi.misc ein Beispiel gefunden, (ist von Nineberry, der weiss was er tut)
Delphi-Quellcode:
Damit müsstest du deine andere Instanz finden, der schickst du dann die Message (und wenn du WM_USER + 4711 sendest, dann musst du natürlich auch auf WM_USER + 4711 abfragen)
procedure CheckOnce;
const TestTitle = 'Nicoles Einweganwendung testing...'; AppTitle = 'Nicoles Einweganwendung'; var hWnd: THandle; begin // einen anderen Titel setzen, so dass wir uns // nicht selbst finden Application.Title:= TestTitle; hWnd:= FindWindow('TApplication', AppTitle); if hWnd <> 0 then begin // Eine andere Instanz läuft schon; // Falls minimiert, wiederherstellen if IsIconic(hWnd) then ShowWindow(hWnd, SW_SHOW); // Diese in den Vordergrund bringen SetForegroundWindow(hWnd); // Uns selbst schließen Halt; end; // Wir sind die erste Instanz -> Titel setzen, so // dass weitere unsfinden Application.Title:= AppTitle; end; /Edit |
Re: Mutex und Programm nicht doppelt starten
Arghhh... es geht leider nicht, er findet das fenster handle nicht...
meine unit sieht jetzt so aus:
Delphi-Quellcode:
unit mutex;
interface implementation uses windows,Dialogs,sysutils,forms,login,messages; const TestTitle = 'StryykeclientTest'; AppTitle = 'Stryykeclient'; var hWnd: THandle; Initialization // einen anderen Titel setzen, so dass wir uns // nicht selbst finden Application.Title:= TestTitle; hWnd := FindWindow('TApplication', AppTitle); ShowMessage(Application.Title); if hWnd <> 0 then begin // Eine andere Instanz läuft schon; ShowMessage('gefunden'); // Falls minimiert, wiederherstellen if IsIconic(hWnd) then ShowWindow(hWnd, SW_SHOW); // Diese in den Vordergrund bringen SetForegroundWindow(hWnd); // Uns selbst schließen Halt; end; // Wir sind die erste Instanz -> Titel setzen, so // dass weitere unsfinden Application.Title:= AppTitle; ShowMessage(Application.Title); finalization // ... und Schluß end. |
Re: Mutex und Programm nicht doppelt starten
Was funktioniert denn nicht?
Ich habe eben deinen Source mal in ein neues Projekt eingefügt und ausprobiert, da passierte das erwartete. |
Re: Mutex und Programm nicht doppelt starten
ok ok jetzt gehts... danke mein application.titel war nach der initialisierung anders...
|
Re: Mutex und Programm nicht doppelt starten
jetzt hab ich aber das Problem, das die Windows Message trotzdem nicht ankommt :|
Delphi-Quellcode:
Windows.SendMessage(hWnd,WM_USER+4711,0,0);
Delphi-Quellcode:
procedure TLoginForm.ApplicationEvents1Message(var Msg: tagMSG;
var Handled: Boolean); begin if MSg.message = WM_USER+4711 then begin ShowMessage('Angekommen'); end; end; |
Re: Mutex und Programm nicht doppelt starten
Das Programm mittels Halt zu beenden ist nicht die beste Wahl.
Besser ist es den Mutex im .dpr file zu platzieren und dort einfach die "Application."-Zeilen in ein if einzuschliessen. Wenn Application.Run nicht aufgerufen wird, dann macht das Programm auch nichts. |
Re: Mutex und Programm nicht doppelt starten
Sorry, kann ich nachvollziehen, verstehe es aber momentan auch nicht.
Das Handle ist richtig, FindWindow liefert das korrekte Fenster, nur das Senden geht irgendwie ins Nirvana und kommt nicht in der Application an (auch Windows-mässig nicht). Hab leider keine Zeit, da auf Forschung zu gehen. :( |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:08 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz