I know I have done this before but can't seem to remember how.
I have a program I have set up to run singleton using the mutex on the executable name. unit GlobalSU;
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 dictate what data to act on. I don't want more than one instance of the program running with the same command line arguments. But I do want to be able to start up a second instance with different arguments.
I did this about a year ago but can't remember how. I modify the name with the command line parameters in the DPR and then test for it with the mutex.
I tried renaming Application.ExeName but it is read only so I must have been changing something else.
Below is code that won't compile but added to clarify what I want to do. btw - the '##" is always the first two characters of the 3rd parameters but I test for it with a 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.
You are using wrong approach. Instead of renaming Application.ExeName
, you should send configurable string to your function that tests 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.
Function CreateSingleInstance is meant to be used once in application because it allocates mutex that will remain active until application terminates and then Windows will automatically close mutex handle.
Note: if MyInstanceName
exceeds MAX_PATH
characters or contains backslash '\'
characters function will fail
CreateMutex documentation
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With