Delphi Limit one instance of a program based on command line parameters

I know that I did it before, but I canโ€™t remember how to do it.

I have a program that I installed to run singleton using a mutex on an executable name. GlobalSU unit

interface function IsAppRunning: Boolean; implementation uses Windows, SysUtils, Forms; function IsAppRunning: Boolean; var rtn : Cardinal; begin result := False; CreateMutex(nil, False, PWideChar(ExtractFileName(Application.ExeName))); rtn := GetLastError; if rtn = ERROR_ALREADY_EXISTS then result := True; end; 

The program accepts certain command line parameters that determine what data should act. I do not want more than one instance of a program working with the same command line arguments. But I want to be able to run the second instance with different arguments.

I did it about a year ago, but I canโ€™t remember how to do it. I change the name with the command line options in DPR and then test it with the mutex.

I tried renaming Application.ExeName, but it is read-only, so I had to change something.

Below is the code that will not compile, but added to clarify what I want to do. btw - "##" is always the first two characters of the 3rd parameter, but I check it with RegEx.

 program EPRmailer; uses Vcl.Forms, uMainMailer in 'uMainMailer.pas' {frmMainMailer}, configXML in 'configXML.pas', GlobalSU in 'GlobalSU.pas', CVUtils in 'CVUtils.pas', QMConst in 'QMConst.pas', ServerAttachmentDMu in 'ServerAttachmentDMu.pas'; {$R *.res} var i : integer; begin for i := 0 to ParamCount do if TestParam('##', ParamStr(i)) then Application.ExeName := Application.ExeName + '-' + ParamStr(i); if IsAppRunning then exit; Application.Initialize; ReportMemoryLeaksOnShutdown := DebugHook <> 0; Application.MainFormOnTaskbar := false; Application.CreateForm(TfrmMainMailer, frmMainMailer); frmMainMailer.RunEPR; end. 
+5
source share
1 answer

You are using the wrong approach. Instead of renaming Application.ExeName you should send a custom string to your function, which checks for duplicate applications.

 function CreateSingleInstance(const InstanceName: string): boolean; var MutexHandle: THandle; begin MutexHandle := CreateMutex(nil, false, PChar(InstanceName)); // if MutexHandle created check if already exists if (MutexHandle <> 0) then begin if GetLastError = ERROR_ALREADY_EXISTS then begin Result := false; CloseHandle(MutexHandle); end else Result := true; end else Result := false; end; var MyInstanceName: string; begin Application.Initialize; // Initialize MyInstanceName here ... if CreateSingleInstance(MyInstanceName) then begin // Form creation ... end else Application.Terminate; end. 

The CreateSingleInstance function is intended to be used once in an application, since it allocates a mutex that remains active until the application terminates, and then Windows will automatically close the mutex handle.

Note: if MyInstanceName exceeds the MAX_PATH characters or contains a backslash '\' , the character function will fail

CreateMutex Documentation

+8
source

Source: https://habr.com/ru/post/1208598/


All Articles