Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Mehrfachaufrufe verhindern... (https://www.delphipraxis.net/45955-mehrfachaufrufe-verhindern.html)

Eselchen 15. Mai 2005 15:26


Mehrfachaufrufe verhindern...
 
Hallo,
ich möchte verhindern können, daß ein Programm mehrfach gestartet wird.
Habe dafür mal diesen Code ausprobiert (stammt aus einem ältern Delphi-Buch), der einen Mehrfachaufruf auf die schon Laufende Application switchen soll:
Delphi-Quellcode:
program App;

uses
  Forms,WinProcs,WinTypes,
  Main in 'Main.pas' {MainForm},

{$R *.RES}

var
  PrevInstance : hWnd;
const
  AppName = 'Applikation';

begin
  PrevInstance := FindWindow ('TApplication',AppName);
   if PrevInstance <> 0 Then
    if IsIconic(PrevInstance) Then ShowWindow(PrevInstance,sw_restore)
                              Else BringWindowToTop(PrevInstance)
   Else
    Begin
      Application.Name := AppName;
      Application.Initialize;
      Application.CreateForm(TMainForm, MainForm);
      Application.Run;
    End;
end.

Das ganze funtzt aber net. Die Mehrfachaufrufe gehen immer noch; mein Problem ist halt, daß ich auf Hardwarelevel programmiere und verhindern muss, daß ich auf die entsprechenden Ports 2x zugreife....


Weiß da jemand was dazu??

Danke mal im Voraus

Gruß Eselchen

[edit=Sharky]Delphi-Tags gesetzt. Mfg, Sharky[/edit]

Kernel32.DLL 15. Mai 2005 15:33

Re: Mehrfachaufrufe verhindern...
 
Erstmal:

:dp: Willkommen in der DP!! :dp:

Das, was dir helfen könnte, sieht so aus:

Delphi-Quellcode:
initialization
  mHandle := CreateMutex(nil, True, 'MSCQ');
  if GetLastError = ERROR_ALREADY_EXISTS then begin // application is already running
    messagebox(application.handle, PChar(alreadyrunning), PChar(errorcaption), MB_ICONERROR);
    halt;
  end;

finalization
  if mHandle <> 0 then CloseHandle(mHandle);
Schreibe es am Besten ans Ende deines Programms.

Übrigens: Bevor du eine Frage stellst, solltest du erstmal auf "Suchen" klicken. Sowas hatten wir nämlich schon ein paar Mal.


Happy coding

kernel32.dll

jfheins 15. Mai 2005 16:40

Re: Mehrfachaufrufe verhindern...
 
Shaman hat mal eine Kompo dafür gemacht:
http://www.delphipraxis.net/internal...hlight=instanz

MrKnogge 15. Mai 2005 18:58

Re: Mehrfachaufrufe verhindern...
 
Bei der JediVCL ist ebenfalls eine Komponente vorhanden, desweiteren habe ich mal folgenden Code gefunden:

Delphi-Quellcode:
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);
          SetForeGroundWindow(hWndMe);
        end;

      Result := TRUE;
    end;

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

Initialization
if BereitsAktiv then
  Halt;

Eselchen 15. Mai 2005 19:38

Re: Mehrfachaufrufe verhindern...
 
Hallo, Zusammen,
Danke für die prompten Antworten; werde dann mal ein bißchen rumprobieren...

@Kernal32.dll:
Die Suche hatte ich versucht, aber nichts in der Richtung gefunden... vermutlich die falschen Suchkriterien verwendet, sorry.

Gruß Eselchen

Hansa 15. Mai 2005 20:14

Re: Mehrfachaufrufe verhindern...
 
Der Vorschlag mit den Semaphoren ist gut ! Häufig wird auch Mutex verwendet, aber davon halte ich nicht viel. Ich mache das so :

Delphi-Quellcode:
(*

Anforderung:

Programm darf nur einmal gestartet werden, bei mehrfachen Start, soll der
Bildschirm genau so aussehen, wie beim Verlassen des Programms. Art des
Programmstarts (Taskleiste, Kommandozeile usw.) soll egal sein.

*)
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
  Result := false;
  GetMem(semName,15);
  GetMem(appClass,15);
  StrPCopy(semName,'sema');
  StrPCopy(appClass,'TApplication');
  StrPCopy(appTitle,ExtractFileName(Application.Title));

  // hSem enthält die Nr. der gestarteten Programminstanz

  hSem := CreateSemaphore(nil,0,1,semName);

  // bei nur einmaligem Start muß hSem = 0 sein

  if (hSem <> 0) and (GetLastError() =
                      ERROR_ALREADY_EXISTS) then
    begin
      CloseHandle(hSem);

      // handle des aktuellen Windows ermitteln
      // und Ändern des Titels, um die andere Instanz zu ermitteln
      hWndMe := FindWindow(appClass,appTitle);
      SetWindowText(hWndMe,'ZZZZZZZZ'); // vorausgesetzt kein Programm heißt so

      hWndMe := FindWindow(appClass,appTitle);
      // falls andere Instanz existiert : diese in Vordergrund bringen,
      // Programm steht dann wieder genau an der Stelle, an der es verlassen wurde

      if (hWndMe <> 0) then
        begin
          BringWindowToTop(hWndMe);
          ShowWindow(hWndMe,SW_SHOWNORMAL);
        end;
      Result := true;
    end;

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

end.
Hammerhart. :shock: Das ist ja mein Code. Nur mit englischen Kommentaren. :mrgreen:

Eselchen 15. Mai 2005 20:47

Re: Mehrfachaufrufe verhindern...
 
Hrmpf.... :gruebel:
ich hab da noch ein Problem mit dem IsIconic in allen Beispielen....
und zwar reagierte das Fenster nicht (außer natürlich mit dem eigentlichen "Abwürgen", das war korrekt!), wenn es "minimized" war; es blieb so. Irgendwo wurde da anscheinend ein Handle falsch, bzw nicht zugewiesen...

Habe die Sache jetzt so gelöst:

if IsIconic (Application.Handle) Then ShowWindow(Application.Handle, SW_RESTORE);

War in einem anderen Thread beschrieben, daß man in solchen Fällen sinnvollerweise das Handle der Applikation und nicht des Fensters zuweist...

Vieleicht hilft's dem einen oder anderen auch weiter, auf jeden Fall tut mein Proggi jetzt so, wie ich's mir vorgestellt hatte.
Danke nochmal

Gruß Eselchen


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:59 Uhr.

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