mirror of
https://github.com/doublecmd/doublecmd.git
synced 2026-06-21 09:58:13 +00:00
190 lines
4.2 KiB
ObjectPascal
190 lines
4.2 KiB
ObjectPascal
unit uUniqueInstance;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, SimpleIPC;
|
|
|
|
type
|
|
|
|
TOnUniqueInstanceMessage = procedure (Sender: TObject; Params: array of UTF8String; ParamCount: Integer) of object;
|
|
|
|
{ TUniqueInstance }
|
|
|
|
TUniqueInstance = class
|
|
private
|
|
FInstanceName: UTF8String;
|
|
FServerIPC: TSimpleIPCServer;
|
|
FClientIPC: TSimpleIPCClient;
|
|
FOnMessage: TOnUniqueInstanceMessage;
|
|
|
|
procedure OnNative(Sender: TObject);
|
|
|
|
procedure CreateServer;
|
|
procedure CreateClient;
|
|
public
|
|
constructor Create(aInstanceName: String);
|
|
destructor Destroy; override;
|
|
|
|
function IsRunInstance: Boolean;
|
|
procedure SendParams;
|
|
procedure SendString(aStr: UTF8String);
|
|
|
|
procedure RunListen;
|
|
procedure StopListen;
|
|
|
|
property OnMessage: TOnUniqueInstanceMessage read FOnMessage write FOnMessage;
|
|
end;
|
|
|
|
function IsUniqueInstance(aInstanceName: String): Boolean;
|
|
|
|
{en
|
|
Returns @true if current application instance is allowed to run.
|
|
Returns @false if current instance should not be run.
|
|
}
|
|
function IsInstanceAllowed: Boolean;
|
|
|
|
var
|
|
UniqueInstance: TUniqueInstance = nil;
|
|
|
|
implementation
|
|
|
|
uses
|
|
StrUtils, FileUtil, uGlobs;
|
|
|
|
const
|
|
Separator = '|';
|
|
|
|
{ TUniqueInstance }
|
|
|
|
procedure TUniqueInstance.OnNative(Sender: TObject);
|
|
var
|
|
sTemp: UTF8String;
|
|
sTempArray: array of UTF8String;
|
|
mtMsgCount: TMessageType;
|
|
I: Integer;
|
|
begin
|
|
if Assigned(FOnMessage) then
|
|
begin
|
|
mtMsgCount:= FServerIPC.MsgType;
|
|
sTemp:= FServerIPC.StringMessage;
|
|
SetLength(sTempArray, mtMsgCount);
|
|
for I:= 0 to mtMsgCount - 1 do
|
|
sTempArray[I] := Copy2SymbDel(sTemp, Separator);
|
|
FOnMessage(Self, sTempArray, mtMsgCount);
|
|
SetLength(sTempArray, 0);
|
|
end;
|
|
end;
|
|
|
|
procedure TUniqueInstance.CreateServer;
|
|
begin
|
|
if FServerIPC = nil then
|
|
begin
|
|
FServerIPC:= TSimpleIPCServer.Create(nil);
|
|
FServerIPC.OnMessage:= @OnNative;
|
|
end;
|
|
if FClientIPC <> nil then
|
|
FreeAndNil(FClientIPC);
|
|
end;
|
|
|
|
procedure TUniqueInstance.CreateClient;
|
|
begin
|
|
if FClientIPC = nil then
|
|
FClientIPC:= TSimpleIPCClient.Create(nil);
|
|
end;
|
|
|
|
function TUniqueInstance.IsRunInstance: Boolean;
|
|
begin
|
|
CreateClient;
|
|
FClientIPC.ServerID:= FInstanceName;
|
|
Result:= FClientIPC.ServerRunning;
|
|
end;
|
|
|
|
procedure TUniqueInstance.SendParams;
|
|
var
|
|
sTemp: UTF8String;
|
|
I: Integer;
|
|
begin
|
|
CreateClient;
|
|
FClientIPC.ServerID:= FInstanceName;
|
|
if not FClientIPC.ServerRunning then Exit;
|
|
sTemp:= EmptyStr;
|
|
for I:= 1 to ParamCount do
|
|
sTemp:= sTemp + Separator + SysToUTF8(ParamStr(I));
|
|
try
|
|
FClientIPC.Connect;
|
|
FClientIPC.SendStringMessage(ParamCount, sTemp);
|
|
finally
|
|
FClientIPC.Disconnect;
|
|
end;
|
|
end;
|
|
|
|
procedure TUniqueInstance.SendString(aStr: UTF8String);
|
|
begin
|
|
CreateClient;
|
|
FClientIPC.ServerID:= FInstanceName;
|
|
if not FClientIPC.ServerRunning then Exit;
|
|
try
|
|
FClientIPC.Connect;
|
|
FClientIPC.SendStringMessage(mtString, aStr + Separator);
|
|
finally
|
|
FClientIPC.Disconnect;
|
|
end;
|
|
end;
|
|
|
|
procedure TUniqueInstance.RunListen;
|
|
begin
|
|
CreateServer;
|
|
FServerIPC.ServerID:= FInstanceName;
|
|
FServerIPC.Global:= True;
|
|
FServerIPC.StartServer;
|
|
end;
|
|
|
|
procedure TUniqueInstance.StopListen;
|
|
begin
|
|
if FServerIPC = nil then Exit;
|
|
FServerIPC.StopServer;
|
|
end;
|
|
|
|
constructor TUniqueInstance.Create(aInstanceName: String);
|
|
begin
|
|
FInstanceName:= aInstanceName;
|
|
end;
|
|
|
|
destructor TUniqueInstance.Destroy;
|
|
begin
|
|
if Assigned(FClientIPC) then
|
|
FreeAndNil(FClientIPC);
|
|
if Assigned(FServerIPC) then
|
|
FreeAndNil(FServerIPC);
|
|
inherited Destroy;
|
|
end;
|
|
|
|
|
|
function IsUniqueInstance(aInstanceName: String): Boolean;
|
|
begin
|
|
Result:= True;
|
|
UniqueInstance:= TUniqueInstance.Create(aInstanceName);
|
|
if UniqueInstance.IsRunInstance then
|
|
begin
|
|
UniqueInstance.SendString('ShowMainForm');
|
|
Exit(False);
|
|
end;
|
|
UniqueInstance.RunListen;
|
|
end;
|
|
|
|
function IsInstanceAllowed: Boolean;
|
|
begin
|
|
Result := (not gOnlyOneAppInstance) or IsUniqueInstance(ApplicationName);
|
|
end;
|
|
|
|
finalization
|
|
if Assigned(UniqueInstance) then
|
|
begin
|
|
UniqueInstance.StopListen;
|
|
FreeAndNil(UniqueInstance);
|
|
end;
|
|
end.
|
|
|