-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathAppSingleInstance.pas
More file actions
68 lines (53 loc) · 1.58 KB
/
Copy pathAppSingleInstance.pas
File metadata and controls
68 lines (53 loc) · 1.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
unit AppSingleInstance;
interface
function AcquireSingleInstance(mutexName: string; waitIfExists: boolean; waitMs: cardinal = 10000): boolean;
implementation
uses
Winapi.Windows,
System.SysUtils;
function ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptor: PWideChar;
StringSDRevision: DWORD; out SecurityDescriptor: PSECURITY_DESCRIPTOR; SecurityDescriptorSize: PULONG): BOOL; stdcall;
external advapi32 name 'ConvertStringSecurityDescriptorToSecurityDescriptorW';
const
MUTEX_SDDL = 'D:(A;;GA;;;SY)(A;;GA;;;BA)(A;;GA;;;AU)';
function AcquireSingleInstance(mutexName: string; waitIfExists: boolean; waitMs: cardinal): boolean;
var
sa: TSecurityAttributes;
sd: PSECURITY_DESCRIPTOR;
err: DWORD;
wr: DWORD;
mutex: THandle;
begin
sd := nil;
if not ConvertStringSecurityDescriptorToSecurityDescriptorW(PWideChar(MUTEX_SDDL), 1, sd, nil) then
exit(false);
try
ZeroMemory(@sa, SizeOf(sa));
sa.nLength := SizeOf(sa);
sa.bInheritHandle := false;
sa.lpSecurityDescriptor := sd;
mutex := CreateMutex(@sa, true, PChar(mutexName));
if mutex = 0 then
exit(false);
err := GetLastError;
if err = ERROR_ALREADY_EXISTS then
begin
if not waitIfExists then
begin
CloseHandle(mutex);
exit(false);
end;
wr := WaitForSingleObject(mutex, waitMs);
if not(wr in [WAIT_OBJECT_0, WAIT_ABANDONED]) then
begin
CloseHandle(mutex);
exit(false);
end;
end;
result := true;
finally
if sd <> nil then
LocalFree(HLOCAL(sd));
end;
end;
end.