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 Suche in: Delphi-Forum, Delphi-Library 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 user profile iconLuckies 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

user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:

Du könntest einen Suche in: Delphi-Forum, Delphi-Library 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(nil01'Programmname');
  if ((Sem <> 0and (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!

user profile icondelphi10 hat folgendes geschrieben Zum zitierten Posting springen:
Letztens bei den Schweizern abgekupfert:
[...]
Kurz und schmerzlos :D
user profile iconHobby-Programmierer hat folgendes geschrieben Zum zitierten Posting springen:
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(nil01'Programmname');
  result:= (((Sem <> 0and
           (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!

user profile iconHobby-Programmierer hat folgendes geschrieben Zum zitierten Posting springen:
wäre folgendes eine Alternative?
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' {TForm1};

{$R *.res}

var
  hWndFirst,
  hWndApp: HWND;
  hMutex: THandle;

begin
  Application.Initialize;
  Application.Title := 'Name';

  // Mehrfachstart unterbinden
  hMutex := CreateMutex(NIL, TRUE, PChar('Name gestartet'));
  if (GetLastError() = ERROR_ALREADY_EXISTS) then begin
    ReleaseMutex(hMutex);
    hWndFirst := FindWindow('TForm1''Name');
    if (hWndFirst <> 0then begin
      hWndApp := GetWindow(hWndFirst, GW_OWNER); // Handle des TApplication-Fensters
      if IsIconic(hWndApp) then
        ShowWindow(hWndApp, SW_RESTORE); // restore, wenn minimiert
      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

user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
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.