How can I run a single instance of my Delphi application on Linux?
I have seen that on Windows it is possible to achieve this through the use of TMutex
or through the JclAppInst
library, I have not found anything about Linux. The JclAppInst library is not usable on linux, while for what concerns the mutex using this code...
var
LMutex : TMutex;
begin
LMutex := TMutex.Create(nil, True, 'D4904154-E778-4762-9C74-BEB567DC4AA4');
if GetLastError <> 183 then
begin
//...do something
end;
FreeAndNil(LMutex);
end;
...I get the following error message:
Named synchronization objects not supported on this platform
CodePudding user response:
As suggested by @AmigoJack, I solved it by locking the same file.
uMyMutex.pas:
unit uMyMutex;
interface
uses
Classes,
SysUtils,
DateUtils;
type
TMutex = class
private
FFilePath: string;
FFileStream: TFileStream;
public
constructor Create(const AName: string);
destructor Destroy; override;
end;
implementation
function GetTempDir: string;
begin
Result := '/tmp/';
end;
constructor TMutex.Create(const AName: string);
var
LMask: UInt16;
begin
inherited Create;
FFileStream := nil;
FFilePath := IncludeTrailingPathDelimiter(GetTempDir) AName '.pid';
LMask := fmOpenReadWrite or fmShareExclusive;
if not FileExists(FFilePath) then
LMask := LMask or fmCreate;
FFileStream := TFileStream.Create(FFilePath, LMask);
end;
destructor TMutex.Destroy;
begin
FreeAndNil(FFileStream);
inherited;
end;
end.
main.pas:
program Test;
uses
System.Classes,
uMyMutex;
var
LPidFileName: string;
begin
LPidFileName := 'test';
try
with TMutex.Create(LPidFileName) do
try
//...do something
finally
Free;
end;
except
on E: EFOpenError do
begin
Writeln(Format('Process already running [%s]; %s', [E.ClassName, E.Message]));
end;
end;
end.