Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Nur eine Instanz des Programms (https://www.delphipraxis.net/1266-nur-eine-instanz-des-programms.html)

rebugger 7. Nov 2002 16:39


Nur eine Instanz des Programms
 
Hallo,
weiß net so recht, ob das hier rein passt... Bitte verschieben, falls nötig.

Wie kann ich einen weiteren Programm-Start verhindern ?
Also, dass nur max. eine Instanz meines Programms geöffnet ist.
Habe zwar einige Komponenten gefunden, wollte aber dann doch den Quellcode, dass mein Programm nicht so aufbläht.

Wäre schön, wenn jemand eine Lösung hätte !
[edit=FuckRacism]AB nach WinAPI[/edit]

RomanK 7. Nov 2002 16:43

Sers rebugger,
das hier ist aus dem EDH:

Zitat:

Verhindern, das ein Programm mehrmals gestartet werden kann


Diese paar Zeilen Code verhindern, dass Dein Programm mehrmals gestartet werden kann.
Schreibe dies ans Ende Deiner Unit (am Besten Unit des Hauptformulars):
Delphi-Quellcode:
Initialization
  mHandle:=CreateMutex(nil,True,'Programmname');
  if GetLastError=ERROR_ALREADY_EXISTS then
    Halt;

finalization
  if mHandle<>0 then
    CloseHandle(mHandle)

end.
Du musst natürlich noch die globale Variable mHandle: THandle deklarieren (z.B. da wo Form1: TForm1 steht).

Als 'Programmname' kann eine beliebige Bezeichnung eingesetzt werden.

Hansa 7. Nov 2002 17:27

Hi,

Stichwort : "Semaphoren", bitte suchen, hab den Link gerade nicht.

Gruß
Hansa

DKamps 7. Nov 2002 17:45

Auf jeden Fall sollte das über die Windows API funktionieren. Beim Start musst Du nachsehen, ob es bereits ein Fenster mit dem gleichen Namen gibt. Wenn ja: MainForm.Close
Leider habe ich den Quellcode von den API-Aufrufen nicht greifbar, aber mein Mitarbeiter hat ein Beispiel im Forum gefunden.

Luckie 7. Nov 2002 17:57

Jungs zerbrecht euch nicht weiter den Kopf. Die Lösungt ist der Mutex bzw. der Semaphor, wobei ich den Mutex vorziehen würde (, weil ich es mit dem Semapohor noch nie gemacht habe :roll: ).

Motzi 7. Nov 2002 18:13

Also ich würde Semaphore vorziehen.. soweit ich weiß kann es mit Mutex Probleme geben! Es gibt Microsoft-Dokumentationen laut denen es vorkommen kann (zumindenst unter Win9x) dass Mutexe nicht korrekt freigegeben werden!

jbg 7. Nov 2002 18:15

Der Mutex entspricht auch viel mehr dem gewünschten Ergebnis, da er im Prinzip als Boolean gesehen werden kann. Ein Semaphore hingegen ist ein "Integer", dessen Wert erniedrigt und erhöht wird. Man kann bei Semaphoren den maximalen Wert festlegen, ab dem geblockt wird. Ein Mutex entspricht somit einem Semaphore mit dem Maximalen Wert 1, nur mit weniger Verwaltungsaufwand.
Da das Programm sowieso nur 1x gestartet werden darf, kommt hier ein Mutex eher in betracht.

Hansa 7. Nov 2002 18:40

Hi Leute,

habt ihr nichts zu tun ? :mrgreen: Code folgt noch. Habe hier eine Function, die in das DPR rein muß, z.B.

IF BereitsAktiv THEN
Aplication.Terminate;

Mutex ist meiner Ansicht nach nicht so gut. Mit Semaphoren (griech.: Signalflagge) wird Windows angezeigt, daß die Anwendung bereits läuft. Bei meinem Bsp. sieht das folgendermaßen aus.

1. User startet Programm und gibt eine halbe Rechnung ein.
2. User macht was anderes und vergißt die halbe Rechnung.
3. Er startet Programm wieder.
4. Semaphore teilt dem Programm mit es sei gestartet, schließt die zweite Instanz und startet sich selbst, wobei es wieder genau mitten in der halben Rechnung steht. Also genau nach dem "Zwischenfall".

Delphi-Quellcode:
unit sema;

interface

uses
  Windows, Messages,SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

function BereitsAktiv: Boolean;

IMPLEMENTATION

function BereitsAktiv: Boolean;
var
  semName,
  appClass: PChar;
  hSem   : THandle;
  hWndMe : HWnd;
  appTitle: Array[0..MAX_PATH] of Char;
begin
  // Init
  Result := FALSE;
  GetMem(semName,15);
  GetMem(appClass,15);
  StrPCopy(semName,'sema');
  StrPCopy(appClass,'TApplication');
  StrPCopy(appTitle,ExtractFileName(Application.Title));

  // Create a Semaphore in memory. If this is the
  // first instance, then hSem's value should be 0.
  hSem := CreateSemaphore(nil,0,1,semName);

  // Check to see if the semaphore exists
  if (hSem <> 0) and (GetLastError() =
                      ERROR_ALREADY_EXISTS) then
    begin
      CloseHandle(hSem);

      // Get the current window's handle then change
      // its title so we can look for the other instance
      hWndMe := FindWindow(appClass,appTitle);
      SetWindowText(hWndMe,'ZZZZZZZ');

      // Search for other instance of this window then bring
      // it to the top of the Z-order stack. We find it by
      // matching the Application Class and
      // Application Title.
      hWndMe := FindWindow(appClass,appTitle);
      if (hWndMe <> 0) then
        begin
          BringWindowToTop(hWndMe);
          ShowWindow(hWndMe,SW_SHOWNORMAL);
        end;

      Result := TRUE;
    end;

  // Destroy PChars
  FreeMem(semName,15);
  FreeMem(appClass,15);
end;

end.
Wem das nicht reicht, soll sich mit Mutex (warum aber ?) beschäftigen. Mir ging es darum, zu verhindern, daß ein Programm 10mal in der Taskleiste steht, was vorher nicht eingeplant war. Mit diesem Bsp. kann man es so oft starten, wie man will, es landet immer nur bei einer Instanz. Ein Start mehrerer wird verhindert, da es immer bei der ersten landet.

Quelltext ist getestet und funktioniert, bis auf die Einbindung in DPR. Da könnte ein Fehler drin sein, aber die eventuelle Korrektur kann ich nachliefern.

Gruß
Hansa :witch:

Christian Seehase 7. Nov 2002 20:11

Moin Zusammen,

ein Mutex hat den prinzipiellen Nachteil, dass er im Falle eines Programmabsturzes, ohne geregeltes Ende, nicht wieder freigegeben wird, was dann, in letzter Konsequenz, heisst, dass das Programm bis zum Neustart des Rechners nicht mehr gestartet werden kann.

Daniel B 7. Nov 2002 20:45

Zitat:

Zitat von Luckie
wobei ich den Mutex vorziehen würde (, weil ich es mit dem Semapohor noch nie gemacht habe :roll: ).

Das ist doch mal ne Aussage. :hello:
ROTFL - ROTFL - ROTFL

Tränen lachend, Daniel :hi:


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:33 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz