Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
854 views
in Technique[技术] by (71.8m points)

delphi - one instance of app per Computer, how?

I am trying to make my app run only once on a computer, My app needs to comunicate to a webservice so it is bad to let it run more than once, currently im using Mutex with this:

MyMsg := RegisterWindowMessage('My_Unique_App_Message_Name');
Mutex := CreateMutex(nil, True, 'My_Unique_Application_Mutex_Name'); 
if (Mutex = 0) OR (GetLastError = ERROR_ALREADY_EXISTS) then
exit;

Currently this works to limit 1 instance of application per user, but my app is being used in a Windows Server Environment where there are 20+ users loged in at a time, so i need to strict it to only run once per server, what i am trying to do is to declare that Mutex as a Global mutex but i fail to do so when i do the next code it doesnt work at all.

 MyMsg := RegisterWindowMessage('My_Unique_App_Message_Name');
 Mutex := CreateMutex(nil, True, 'GlobalMy_Unique_Application_Mutex_Name'); 
 if (Mutex = 0) OR (GetLastError = ERROR_ALREADY_EXISTS) then
 begin
 exit

So am i doing something wrong? is there any other reliable way of not letting a second instance of my app to run?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

By default, lpMutexAttributes = nil created mutexes are accessible only by the user running the process. The mutex needs to be accessible to all users.

Null DACL security descriptor

Do this by using a security descriptor with a null DACL. Please find below the code that I use for single instance applications/services

//Creates a mutex to see if the program is already running.
function IsSingleInstance(MutexName : string; KeepMutex : boolean = true):boolean;
const MUTEX_GLOBAL = 'Global'; //Prefix to explicitly create the object in the global or session namespace. I.e. both client app (local user) and service (system account)

var MutexHandel : THandle;
    SecurityDesc: TSecurityDescriptor;
    SecurityAttr: TSecurityAttributes;
    ErrCode : integer;
begin
  //  By default (lpMutexAttributes =nil) created mutexes are accessible only by
  //  the user running the process. We need our mutexes to be accessible to all
  //  users, so that the mutex detection can work across user sessions.
  //  I.e. both the current user account and the System (Service) account.
  //  To do this we use a security descriptor with a null DACL.
  InitializeSecurityDescriptor(@SecurityDesc, SECURITY_DESCRIPTOR_REVISION);
  SetSecurityDescriptorDacl(@SecurityDesc, True, nil, False);
  SecurityAttr.nLength:=SizeOf(SecurityAttr);
  SecurityAttr.lpSecurityDescriptor:=@SecurityDesc;
  SecurityAttr.bInheritHandle:=False;

  //  The mutex is created in the global name space which makes it possible to
  //  access across user sessions.
  MutexHandel := CreateMutex(@SecurityAttr, True, PChar(MUTEX_GLOBAL + MutexName));
  ErrCode := GetLastError;

  //  If the function fails, the return value is 0
  //  If the mutex is a named mutex and the object existed before this function
  //  call, the return value is a handle to the existing object, GetLastError
  //  returns ERROR_ALREADY_EXISTS.
  if {(MutexHandel = 0) or }(ErrCode = ERROR_ALREADY_EXISTS) then
  begin
    result := false;
    closeHandle(MutexHandel);
  end
  else
  begin
    //  Mutex object has not yet been created, meaning that no previous
    //  instance has been created.
    result := true;

    if not KeepMutex then
       CloseHandle(MutexHandel);
  end;

  // The Mutexhandle is not closed because we want it to exist during the
  // lifetime of the application. The system closes the handle automatically
  //when the process terminates.
end;

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...