我尝试创建一个只允许所有Windows用户使用单个实例的应用程序。
我目前正在通过打开要写入的文件并将其保持打开来执行此操作。这种方法安全吗?你知道使用C的替代方法吗?
答案 0 :(得分:5)
标准解决方案是在应用程序启动期间创建全局mutex。应用程序第一次启动时,这将成功。在后续尝试中,它将失败,这是您停止加载第二个实例的线索。
您可以通过调用CreateMutex
function在Windows中创建互斥锁。正如链接文档所指示的那样,使用Global\
为互斥锁的名称添加前缀可确保它对所有终端服务器会话都可见,这就是您想要的。相比之下,Local\
前缀只会使其在创建它的用户会话中可见。
int WINAPI _tWinMain(...)
{
const TCHAR szMutexName[] = TEXT("Global\\UNIQUE_NAME_FOR_YOUR_APP");
HANDLE hMutex = CreateMutex(NULL, /* use default security attributes */
TRUE, /* create an owned mutex */
szMutexName /* name of the mutex */);
if (GetLastError() == ERROR_ALREADY_EXISTS)
{
// The mutex already exists, meaning an instance of the app is already running,
// either in this user session or another session on the same machine.
//
// Here is where you show an instructive error message to the user,
// and then bow out gracefully.
MessageBox(hInstance,
TEXT("Another instance of this application is already running."),
TEXT("Fatal Error"),
MB_OK | MB_ICONERROR);
CloseHandle(hMutex);
return 1;
}
else
{
assert(hMutex != NULL);
// Otherwise, you're the first instance, so you're good to go.
// Continue loading the application here.
}
}
虽然有些人可能认为它是可选的,但由于操作系统会为您处理,我总是提倡明确清理并在您的应用程序退出时调用ReleaseMutex
和CloseHandle
。这并不能解决您崩溃并且没有机会运行清理代码的情况,但正如我所提到的,操作系统将在拥有进程终止后清理任何悬空互斥锁。