Newsgroup: it.comp.lang.delphi
Titolo: Limitare avvio eseguibile

vorei impedire all'utonto di avviare 2 o piu' istanze della stessa
applicazione Delphi, finora non mi ero posto il problema, ma
ho verificato che puo' succedere.
dove posso intervenire ?
Maurizio 

 wrote in message 
news:4565f654$0$13769$4faf...@reader3.news.tin.it...

http://delphi.about.com/library/code/ncaa110203a.htm
Acqua 

> dove posso intervenire ?
rettifico il messaggio precedente.
Parti da qui:
http://delphi.about.com/library/weekly/aa110203a.htm
Acqua 

"Maurizio" ha scritto nel messaggio

E una FAQ:
Come prevenire nuove istanze di un'applicazione in Delphi, ovvero fare in
modo che si possa aprire una volta sola?
Lo puoi fare usando le API di Windows, inserendo questo codice nel
file di progetto (.dpr). Ricordati anche di aggiungere la unit Windows nella
tua clausola uses.
var  PrevInstHandle: THandle;
begin
PrevInstHandle := CreateMutex(nil, False,
   'InserireUnaStringaUnivocaCheIdentificaIlProgramma');
if (GetLastError <> ERROR_ALREADY_EXISTS)
 and (PrevInstHandle <> 0) then
 begin
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end;
Ciao
ACSH
-- 
Il più grande sbaglio nel progettare software
a prova di stupido è sottostimare l'enorme
ingegnosità degli stupidi. 

>
[...]
ti ringrazio del'indicazione , ma ci sarebbe un'ulteriore possibilita'
1) l'eseguibile risiede in un server , e quindi i vari Client devono poterlo
eseguire
2) ogni client deve poter eseguire una sola istanza
3) nel caso di un'applicativo .Net (sia questo con Vcl.Net o WinForm) , non 
so
se si possano usare le Api per Win32
se ' una Faq , dammi l'intestazione , che la cerco , tu come Zarko Gajic 
proponete
l'uso di un Mutex , sbaglio o in passato Marco Cantu' aveva scritto che i 
Mutex
avevano anche controindicazioni (almeno per D4) ora uso D2006 Win32
Maurizio 

 avevano anche controindicazioni (almeno per D4) ora uso D2006 Win32
I mutex prescindono da delphi.
Trattandosi di una risorsa offerta dal sistema operativo, delphi c'entra 
ben poco, idem dicasi per powerbuilder o c++.
Non spetta al linguggio fornire sistemi per la sicronia dei processi 
(come ben si evince da quella cosa strana e sconosciuta ai piu che si 
chiama "TEORIA DEI SISTEMI OPERATIVI"....).
Al massimo il linguaggio puo darti dei wrapper per semplificarti la 
vita, ma restano dei wrapper e nulla +.
A parte cio, scritto DOVE? Hai link, pagine dei suoi libri o cose del 
genere?
A.

> genere?
mi pare averlo letto su Mastering Delphi 4 , vado in cerca , se ho 
interpretato
bene , posto il capitolo.
ciao Maurizio 

 uso D2006 Win32
Una controindicazione che puo' avere un Mutex e' su sistemi XP
dove si possono utilizzare piu' account contemporaneamente.
Ogni account ha il proprio desktop e le proprie risorse, quindi
possono coesistere mutex dallo stesso nome su piu' account.
Il modo per prevenire questo fatto e' di anteporre " Global\\ "
al nome del mutex (ma questo funziona solo su XP e da'
errore su Win Playstation ... ehm ... Win 98, quindi bisogna
gestire il tutto).
Altri inconvenienti non ne vedo.
Le FAQ non aggiornatissime (per usare un eufemismo ...)
le trovi googlando su questo stesso gruppo.
Ciao
-- 
ACSH
[TurboDelphi]
Chi fa da se', fatica il doppio 

Maurizio ha detto: in data 23/11/2006 20.28:

Io uso il seguente codice nelle mie applicazioni.
Saluti, Riccardo.
.......
.......
   if not CheckPrevious.RestoreIfRunning(Application.Handle, 1) then
     begin
       Application.Initialize;
       ......
       ......
       Application.Run;
     end;
//////////////////////////////////////////
unit CheckPrevious;
interface
uses Windows, SysUtils;
function RestoreIfRunning(const AppHandle : THandle; MaxInstances : 
integer = 1) : boolean;
implementation
type
   PInstanceInfo = ^TInstanceInfo;
   TInstanceInfo = packed record
     PreviousHandle : THandle;
     RunCounter : integer;
   end;
var
   MappingHandle: THandle;
   InstanceInfo: PInstanceInfo;
   MappingName : string;
   RemoveMe : boolean = True;
function RestoreIfRunning(const AppHandle : THandle; MaxInstances : 
integer = 1) : boolean;
begin
   Result := True;
   MappingName :=StringReplace(ParamStr(0),'\','',[rfReplaceAll, 
rfIgnoreCase]);
   MappingHandle := CreateFileMapping($FFFFFFFF,
                                      nil,
                                      PAGE_READWRITE,
                                      0,
                                      SizeOf(TInstanceInfo),
                                      PChar(MappingName));
   if MappingHandle = 0 then
{$IFDEF DELPHI6_UP}
     RaiseLastOSError {$ELSE}
     RaiseLastWin32Error {$ENDIF}
   else
   begin
     if GetLastError <> ERROR_ALREADY_EXISTS then
     begin
       InstanceInfo := MapViewOfFile(MappingHandle,
                                     FILE_MAP_ALL_ACCESS,
                                     0,
                                     0,
                                     SizeOf(TInstanceInfo));
       InstanceInfo^.PreviousHandle := AppHandle;
       InstanceInfo^.RunCounter := 1;
       Result := False;
     end
     else //already runing
     begin
       MappingHandle := OpenFileMapping(FILE_MAP_ALL_ACCESS, False, 
PChar(MappingName));
       if MappingHandle <> 0 then
       begin
         InstanceInfo := MapViewOfFile(MappingHandle,
                                       FILE_MAP_ALL_ACCESS,
                                       0,
                                       0,
                                       SizeOf(TInstanceInfo));
         if InstanceInfo^.RunCounter >= MaxInstances then
         begin
           RemoveMe := False;
           if IsIconic(InstanceInfo^.PreviousHandle) then
             ShowWindow(InstanceInfo^.PreviousHandle, SW_RESTORE);
           SetForegroundWindow(InstanceInfo^.PreviousHandle);
         end
         else
         begin
           InstanceInfo^.PreviousHandle := AppHandle;
           InstanceInfo^.RunCounter := 1 + InstanceInfo^.RunCounter;
           Result := False;
         end
       end;
     end;
   end;
end;
initialization
finalization
   //remove one instance
   if RemoveMe then
   begin
     MappingHandle := OpenFileMapping(FILE_MAP_ALL_ACCESS, False, 
PChar(MappingName));
     if MappingHandle <> 0 then
     begin
       InstanceInfo := MapViewOfFile(MappingHandle,
                                   FILE_MAP_ALL_ACCESS,
                                   0,
                                   0,
                                   SizeOf(TInstanceInfo));
       InstanceInfo^.RunCounter := -1 + InstanceInfo^.RunCounter;
     end
     else
{$IFDEF DELPHI6_UP}
     RaiseLastOSError; {$ELSE}
     RaiseLastWin32Error; {$ENDIF}
   end;
   if Assigned(InstanceInfo) then UnmapViewOfFile(InstanceInfo);
   if MappingHandle <> 0 then CloseHandle(MappingHandle);
end.
////////////////////////////////////////////////////////////