Entwickler-Ecke
Windows API - eindeutige Programmidentifizierung
fuggaz - Di 06.04.10 13:44
Titel: eindeutige Programmidentifizierung
Hey,
wie kann ich eindeutig(soweit möglich) mein eigenes Programm erkennen, falls dieses schon läuft?
Nachgucken, ob es unter Prozesse schon aufgelistet ist, ist ja nicht eindeutig.
Könnte ja jeder den gleichen Programmnamen wie meinen haben.
Gibt es eine "globale Variable", die ich anlegen kann und die ein anderes Programm dann auslesen kann?
Dann könnte ich dort eine Zeichenkette reinpacken zur Identifizierung.
Narses - Di 06.04.10 14:01
Moin!
Du könntest einen
MUTEX anlegen. :nixweiss:
cu
Narses
Gausi - Di 06.04.10 16:06
Falls du das dafür brauchst, dass dein Programm nur einmal gestartet werden soll, dann ist evtl. die Unit OneInst was für dich. Die gibt es auf
Luckies
Webseite [
http://michael-puff.de/Developer/Delphi/Nico/]. :D
Da wird das auch über einen Mutex gemacht, und eventuelle Parameter werden weitergereicht.
dummzeuch - Di 06.04.10 21:48
Narses hat folgendes geschrieben : |
Du könntest einen MUTEX anlegen. :nixweiss:
|
Ein Event Objekt waere evtl. besser, denn dann koennte das Programm darueber auch gleich die bereits laufende Instanz aktivieren.
Xion - Di 06.04.10 22:39
Mir fallen da spontan 2 Möglichkeiten ein.
Entweder du legst bei Programmstart ne Datei an, und guckst einfach ob die schon existiert. Das hat definitiv den Nachteil, dass du dein Programm nichtmehr öffnen kannst, wenns mal abgestürzt ist und die Datei nicht ordnungsgemäß gelöscht hat...ich frag mich wie das OpenOffice oder Adobe machen.
Alternativ kannst du per FindWindow gucken ob der Prozess schon da ist (nicht nur mit Fenstercaption sondern auch mit Klassennamen) und dann vielleicht einfach diesen Prozess fragen, ob er der richtige ist (ne Message als Anfrage schicken und gucken was zurückkommt). Da kannst du z.B. ne 20 stellige Nummer zurückschicken, dass das ein andres Programm als Antwort auf die selbe message macht ist sehr unwahrscheinlich.
fuggaz - Mi 07.04.10 01:55
Danke für die Antworten.
Die OneInst Unit löst mein Problem.
mfg fuggaz
delphi10 - Mi 07.04.10 13:21
Letztens bei den Schweizern abgekupfert:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| procedure TForm1.FormShow(Sender: TObject); Var sem: THANDLE; begin Sem := CreateSemaphore(nil, 0, 1, 'Programmname'); if ((Sem <> 0) and (GetLastError = ERROR_ALREADY_EXISTS)) then begin CloseHandle(Sem); ShowMessage('Programmname is already running.'); Application.Terminate; end; end; |
Kurz und schmerzlos :D
Hobby-Programmierer - Mi 07.04.10 14:00
Hallo ...,
sollte man net so früh wie möglich auf eine vorhandene Instanz prüfen? Ich dachte immer sowas gehört in die Project - Datei bevor Formulare erzeugt werden :gruebel:
LG Mario
Narses - Mi 07.04.10 14:12
Moin!
delphi10 hat folgendes geschrieben : |
Letztens bei den Schweizern abgekupfert:
[...]
Kurz und schmerzlos :D |
Hobby-Programmierer hat folgendes geschrieben : |
sollte man net so früh wie möglich auf eine vorhandene Instanz prüfen? Ich dachte immer sowas gehört in die Project - Datei bevor Formulare erzeugt werden :gruebel: |
Jup, so ist es. Deshalb ist der schweizerische Vorschlag hier auch nicht angebracht. Besser Luckie´s Unit nehmen. ;)
cu
Narses
Hobby-Programmierer - Do 08.04.10 01:52
Moin Narses :)
wäre folgendes eine Alternative?
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22:
| var Sem: THandle;
function IsInstanceExists: Boolean; begin Sem:= CreateSemaphore(nil, 0, 1, 'Programmname'); result:= (((Sem <> 0) and (GetLastError = ERROR_ALREADY_EXISTS) and (MessageDlg('Programm bereits gestartet !', mtWarning, [mbIgnore, mbAbort], 0) <> mrIgnore))); end;
begin
if not IsInstanceExists then begin Application.Initialize; Application.CreateForm(TForm1, Form1); Application.Run; end;
CloseHandle(Sem);
end. |
LG Mario
Narses - Do 08.04.10 09:31
Moin!
Ich mache das normalerweise so:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40:
| program Name;
uses Forms, Windows, Unit1 in 'Unit1.pas' ;
{$R *.res}
var hWndFirst, hWndApp: HWND; hMutex: THandle;
begin Application.Initialize; Application.Title := 'Name';
hMutex := CreateMutex(NIL, TRUE, PChar('Name gestartet')); if (GetLastError() = ERROR_ALREADY_EXISTS) then begin ReleaseMutex(hMutex); hWndFirst := FindWindow('TForm1', 'Name'); if (hWndFirst <> 0) then begin hWndApp := GetWindow(hWndFirst, GW_OWNER); if IsIconic(hWndApp) then ShowWindow(hWndApp, SW_RESTORE); SetForegroundWindow(hWndFirst); BringWindowToTop(hWndFirst); end; Application.Terminate; Application.ProcessMessages; Exit; end;
Application.CreateForm(TForm1, Form1); Application.Run;
ReleaseMutex(hMutex); end. |
Ich gestehe, ich habe die Vor-/Nachteilsliste von Mutex/Semaphor gerade nicht auswendig parat, deshalb kann ich das nicht wirklich gut vergleichen. Aber im Zweifel sollte das MSDN dir da weiter helfen. ;)
cu
Narses
Martok - Do 08.04.10 10:49
Narses hat folgendes geschrieben : |
Ich gestehe, ich habe die Vor-/Nachteilsliste von Mutex/Semaphor gerade nicht auswendig parat, deshalb kann ich das nicht wirklich gut vergleichen. |
Beides sind ja erstmal Synchronisationsobjekte, die hier zweckentfremdet werden. Wichtig ist hier nur, dass sie Namen haben können und Namenskonflikte Fehler hervorrufen (deswegen geht z.B. ein Atom nicht).
Ansonsten ist der Unterschied ja, dass Mutexe
Mutually
Exclusive sind, also nur einmal gehalten werden können, Semaphoren aber mehrere Eigentümer haben können. Das spielt hier aber wie gesagt genau keine Rolle.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!