在所有用户之间制作单例应用程序

时间:2014-05-10 09:55:06

标签: c windows winapi single-instance

我尝试创建一个只允许所有Windows用户使用单个实例的应用程序。

我目前正在通过打开要写入的文件并将其保持打开来执行此操作。这种方法安全吗?你知道使用C的替代方法吗?

1 个答案:

答案 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.
   }
}

虽然有些人可能认为它是可选的,但由于操作系统会为您处理,我总是提倡明确清理并在您的应用程序退出时调用ReleaseMutexCloseHandle。这并不能解决您崩溃并且没有机会运行清理代码的情况,但正如我所提到的,操作系统将在拥有进程终止后清理任何悬空互斥锁。