我有一个访问某些文件和系统资源的应用程序,因此可能只有一个应用程序实例处于活动状态.这是通过创建一个命名的信号量并在已经分配了信号量时停止应用程序运行来实现的.在过去(阅读:当Windows XP是最常见的操作系统时)运行良好,但现在我们注意到旧代码不适用于多个用户会话.
这里的旧代码:
hInstanceSem := CreateSemaphore(nil, 0, 1, PChar(GetProductName(Application.ExeName)));
if (hInstanceSem <> 0) and (GetLastError = ERROR_ALREADY_EXISTS) then
// do not run the Application
Run Code Online (Sandbox Code Playgroud)
所以我做了一些研究,了解了全局信号量并将代码更改为:
function CreateGlobalSemaphor(SemaphorName: String): Cardinal;
var
desc: SECURITY_DESCRIPTOR;
att : TSecurityAttributes;
sem : Cardinal;
begin
att.nLength := SizeOf(TSecurityAttributes);
att.bInheritHandle := true;
att.lpSecurityDescriptor := @desc;
InitializeSecurityDescriptor(att.lpSecurityDescriptor, SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(att.lpSecurityDescriptor, True, nil, False);
sem := CreateSemaphore(@att, 0, 1, PChar('Global\' + SemaphorName));
if (sem <> 0) and (GetLastError() <> ERROR_ALREADY_EXISTS) then begin
Result := sem;
end else begin
Result := …Run Code Online (Sandbox Code Playgroud)