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 multiple instanzen (>2) einer Anwendung (https://www.delphipraxis.net/130157-multiple-instanzen-2-einer-anwendung.html)

danieleh 4. Mär 2009 08:41


multiple instanzen (>2) einer Anwendung
 
Hallo

Mit der Erstellung von mehreren (Global) Mutexes versuche ich eine Terminal-Server Anwendung auf 5 Instanzen zu limitieren (über die Sessions hinweg).
Etwas mit der Logik oder meinem Verständnis stimmt allerdings nicht ganz.
Die Mutexes werden zwar wie geplant nacheinnader erstellt, doch sie werden nicht ordnungsgemäss released wenn eine Instanz schliesst.

Also so:

Instanz 1: Global\{03D1CB1A-5C2C-4B0D-9311-F585653FF735}
Instanz 2: Global\{03D1CB1A-5C2C-4B0D-9311-F585653FF734}
Instanz 3: Global\{03D1CB1A-5C2C-4B0D-9311-F585653FF733}
Instanz 4: Global\{03D1CB1A-5C2C-4B0D-9311-F585653FF732}
Instanz 5: Global\{03D1CB1A-5C2C-4B0D-9311-F585653FF731}
Instanz 6: Global\{03D1CB1A-5C2C-4B0D-9311-F585653FF730} --> wird angehalten

schliesse ich zb. Instanz 4 sollte diese frei werden und eine weitere Instanz geöffnet werden können.
Dem ist aber nicht so. Mutex von Instanz 4 wird erst dann wieder frei, wenn ich auch die Instanz 5 schliesse.


Delphi-Quellcode:

var
  i: integer;
  mH: THandle;
  mutex_x: string;

const
 mutex_0: 'Global\{03D1CB1A-5C2C-4B0D-9311-F585653FF730}'

initialization

    sl := TStringList.Create;
    sl.CommaText := 'Global\{03D1CB1A-5C2C-4B0D-9311-F585653FF730}, ' +
                    'Global\{03D1CB1A-5C2C-4B0D-9311-F585653FF731}, ' +
                    'Global\{03D1CB1A-5C2C-4B0D-9311-F585653FF732}, ' +
                    'Global\{03D1CB1A-5C2C-4B0D-9311-F585653FF733}, ' +
                    'Global\{03D1CB1A-5C2C-4B0D-9311-F585653FF734}, ' +
                    'Global\{03D1CB1A-5C2C-4B0D-9311-F585653FF735}';

    for i := 0 to sl.Count-1 do
    begin
      if openmutex(MUTEX_ALL_ACCESS, False, (PChar(sl[i])))=0
      then begin
       mutex_x:= sl[i];
      end;
    end;
    sl.Free;
    if mutex_x=mutex_0 then
    begin
      MessageBox(0, PChar(MSG004), nil, MB_OK or MB_ICONEXCLAMATION);
      Halt(0);
    end else
    mH := CreateMutex(nil,True,(PChar(mutex_x)));


finalization

  if mH <> 0 then
  begin
   // ReleaseMutex(mH);
   // mH := 0;
    CloseHandle(mH)
  end;
Habe jede erdenkliche Variante ausprobiert und bin am Ende meines Alphabets.
Vielleicht hat jemand eine Erklärung ?

himitsu 4. Mär 2009 09:53

Re: multiple instanzen (>2) einer Anwendung
 
ich tipp jetzt einfach mal drauf, daß Anwendungen mit einem höcheren "Wert" noch ein Handle auf tiefere Mutex haben :gruebel:, welche natürlich beim beenden der Programme von Windows dann freigegeben werden. (schön, daß Windows jetzt aufräumt ... unter Win9x hättest du da viel Spaß)
> evnetuell OpenMutex

du solltest auch die Schleife verlassen, wenn du was gefunden hast und das mit OpenMutex geöffnete auch wieder schließen :zwinker:
Delphi-Quellcode:
for i := 0 to sl.Count-1 do
begin
  if openmutex(MUTEX_ALL_ACCESS, False, (PChar(sl[i])))=0
  then begin
    mutex_x:= sl[i];
    break; <<<
  end;
end;
aber eigentlich brauchst du nur mit CreateMutex alle Möglichkeiten durchprobieren und wenn nichts frei war, dann beenden.
Delphi-Quellcode:
Const mutex: Array[0..4] of String = (
  'Global\{03D1CB1A-5C2C-4B0D-9311-F585653FF735}',
  'Global\{03D1CB1A-5C2C-4B0D-9311-F585653FF733}',
  'Global\{03D1CB1A-5C2C-4B0D-9311-F585653FF734}',
  'Global\{03D1CB1A-5C2C-4B0D-9311-F585653FF732}',
  'Global\{03D1CB1A-5C2C-4B0D-9311-F585653FF731}');

Initialization
  For i := 0 to High(mutex) do Begin
    mH := CreateMutex(nil, True, PChar(mutex_x));
    If mH <> 0 Then Break;
  End;
  If mH = 0 Then Begin
    MessageBox(0, PChar(MSG004), nil, MB_OK or MB_ICONEXCLAMATION);
    Halt(0);
  End;

Finalization
  If mH <> 0 Then ReleaseMutex(mH);

End.

mirage228 4. Mär 2009 10:02

Re: multiple instanzen (>2) einer Anwendung
 
Alternativ: Mit Semaphoren und der undokumentierten NT-Funktion NtQuerySemaphore kannst Du die aktuelle Anzahl rausfinden (ab Windows NT/2000).

Viele Grüße

danieleh 4. Mär 2009 12:18

Re: multiple instanzen (>2) einer Anwendung
 
hallo himitsu

An das break hatte ich zwar auch gedacht, aber ohne Erfolg.
Dein Ansatz ist natürlich sehr elegant, aber es ist zum verzweifeln, der erste wird gesetzt aber die anschliessenden werden ignoriert.
Es ist als ob die erste mutex "überschrieben" wird. Wenn ich hingegen die Mutex abfrage, dann hab ich wieder das ursprüngliche Problem.

Delphi-Quellcode:
  For i := 0 to High(mutex) do Begin
 // if openmutex(MUTEX_ALL_ACCESS, False, PChar(mutex[i])) = 0 then
   mH := CreateMutex(nil, True, Pchar(mutex[i]));
    If mH <> 0 Then Break;
  End;
  If mH = 0 Then Begin
    MessageBox(0, PChar(MSG004), nil, MB_OK or MB_ICONEXCLAMATION);
    Halt(0);
  End;
wenn man testet
Delphi-Quellcode:
  For i := 0 to High(mutex) do Begin
      if openmutex(MUTEX_ALL_ACCESS, False, PChar(mutex[i])) = 0
      then showmessage((mutex[i]) + ' null') else showmessage((mutex[i]) +' not null') ;
  End;
dann ist tatsächlich nur die erste in der Liste not null.

mirage228:
weisst Du zufällig ob dass mit den Semaphoren auch mit TerminalServer (und über sessions hinweg) auch klappt?

himitsu 4. Mär 2009 12:45

Re: multiple instanzen (>2) einer Anwendung
 
ich hab mal sozusagen in MSDN-Library durchsuchenCreateMutex reingeschaut .... :angel2:

Delphi-Quellcode:
Const mutex: Array[0..4] of AnsiString = (
  'Global\{03D1CB1A-5C2C-4B0D-9311-F585653FF735}',
  'Global\{03D1CB1A-5C2C-4B0D-9311-F585653FF733}',
  'Global\{03D1CB1A-5C2C-4B0D-9311-F585653FF734}',
  'Global\{03D1CB1A-5C2C-4B0D-9311-F585653FF732}',
  'Global\{03D1CB1A-5C2C-4B0D-9311-F585653FF731}');

Var i: Integer;
  mH: THandle;

Initialization
  For i := 0 to High(mutex) do Begin
    mH := CreateMutexA(nil, True, PAnsiChar(mutex[i]));
    If mH <> 0 Then
      If GetLastError = ERROR_ALREADY_EXISTS Then Begin
        ReleaseMutex(mH);
        mH := 0;
      End Else Break;
  End;
  If mH = 0 Then Begin
    MessageBox(0, PChar(MSG004), nil, MB_OK or MB_ICONEXCLAMATION);
    Halt(0);
  End;

Finalization
  If mH <> 0 Then ReleaseMutex(mH);

End.

mjustin 4. Mär 2009 13:30

Re: multiple instanzen (>2) einer Anwendung
 
Zitat:

Zitat von danieleh
Hallo
Mit der Erstellung von mehreren (Global) Mutexes versuche ich eine Terminal-Server Anwendung auf 5 Instanzen zu limitieren (über die Sessions hinweg).

JclAppinstances in der JCL bietet eine Funktion zur Limitierung auf N Instanzen, eventuell kamm man dort etwas abschauen

mirage228 4. Mär 2009 13:44

Re: multiple instanzen (>2) einer Anwendung
 
Zitat:

Zitat von danieleh
weisst Du zufällig ob dass mit den Semaphoren auch mit TerminalServer (und über sessions hinweg) auch klappt?

Laut Doku bei Mirosoft unterstüzt MSDN-Library durchsuchenCreateSemaphore auch "Global\" und sollte somit auch auf TerminalServer funktionieren, getestet habe ich das allerdings nicht...

danieleh 4. Mär 2009 14:31

Re: multiple instanzen (>2) einer Anwendung
 
himitsu
die Mutexes hats nun ordnungsgemäss erstellt.
Dennoch gibts weiterhin das Problem dass sie nicht freigegeben werden beim schliessen (bevor man alle geschlossen hat) - genau so wie am Anfang.

mjustin
werde mir die Komponenten anschauen
- und auch die Semaphoren. Danke

Ich würde trotzdem gerne verstehen weshalb es sich mit den Mutexes so verhält - und es mit denen hinkriegen.

himitsu 4. Mär 2009 16:18

Re: multiple instanzen (>2) einer Anwendung
 
schon komisch ... RelaseMutex scheint wohl nicht so zu Funktionieren, wie ich mir denk :gruebel:,
aber mit CloseHandle geht es nun endlich :angel:

Delphi-Quellcode:
Const mutex: Array[0..4] of AnsiString = (
  'Global\{03D1CB1A-5C2C-4B0D-9311-F585653FF735}',
  'Global\{03D1CB1A-5C2C-4B0D-9311-F585653FF733}',
  'Global\{03D1CB1A-5C2C-4B0D-9311-F585653FF734}',
  'Global\{03D1CB1A-5C2C-4B0D-9311-F585653FF732}',
  'Global\{03D1CB1A-5C2C-4B0D-9311-F585653FF731}');

Var i: Integer;
  mH: THandle;

Initialization
  For i := 0 to High(mutex) do Begin
    mH := CreateMutexA(nil, True, PAnsiChar(mutex[i]));
    If mH <> 0 Then
      If GetLastError = ERROR_ALREADY_EXISTS Then Begin
        CloseHandle(mH);
        mH := 0;
      End Else Break;
  End;
  If mH = 0 Then Begin
    MessageBox(0, PChar('nix frei'), 'Error', MB_OK or MB_ICONEXCLAMATION);
    Halt(0);
  End Else
    MessageBox(0, PChar(IntToStr(i + 1)), 'OK', MB_OK or MB_ICONINFORMATION);

Finalization
  If mH <> 0 Then CloseHandle(mH);

End.

mjustin 4. Mär 2009 17:48

Re: multiple instanzen (>2) einer Anwendung
 
Zitat:

Zitat von danieleh
mjustin
werde mir die Komponenten anschauen

"JCL" wie "Jedi Code Library", also keine Komponenten mit größeren Installationsorgien nötig. Einfach in den Suchpfad und verwenden. Die Installer von JCL (und JVCL) sind allerdings auch schon beeindruckend für ein Delphi Open Source Projekt.


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:11 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