• 只能同时运行一个实例的程序


          很多情况下,程序会要求同一时间内只能运行一个实例,以免发生系统崩溃、数据遭破坏等后果。最常用被使用的是创建一个有名字的Mutex(互斥)的方法。程序的实例或对象含有Mutex之后,同一时间内将只能被一个线程访问。

          Windows给我们提供了CreateMutex函数来创建Mutex。原型如下:

    HANDLE WINAPI CreateMutex(
      __in_opt  LPSECURITY_ATTRIBUTES lpMutexAttributes,
      __in      BOOL bInitialOwner,//Mutex的所有者的句柄。
      __in_opt  LPCTSTR lpName//Mutex对象的名称。
    );

          我们为互斥体起一个名字,作为CreateMutex的第三个参数。那么程序运行时,将使用CreateMutex创建一个互斥体,再次运行将再创建一个同名的互斥体从而引发错误信息,此时GetLastError函数将返回ERROR_ALREADY_EXISTS错误信息。

          利用这一点,我们可以达到只让程序运行一个实例的目的。代码如下。

     1 #include <windows.h>
     2 #include <tchar.h>
     3 int _stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCMD)
     4 {
     5  CreateMutex(NULL,FALSE,_T("Mutex"));
     6  if(GetLastError()==ERROR_ALREADY_EXISTS)
     7   return FALSE;
     8  MessageBox(NULL,_T("Program Success !"),_T("Mutex"),MB_OK);
     9  return 0;
    10 }

          但这样并不完善。当用户想要运行该程序时,如果已经有实例正在运行,最好能激活运行中实例的窗口,如果该窗口处于最小化则将其弹出

     1 BOOL MyMUTEX()
     2 {
     3  //1、创建Mutex
     4  HANDLE hMutex=CreateMutex(NULL,TRUE,_T("Mutex"));
     5  if (hMutex == NULL)
     6  {
     7   return FALSE;
     8  }
     9  //2、如果Mutex已经存在并且正在运行
    10  if (GetLastError() == ERROR_ALREADY_EXISTS)
    11  {
    12   //3、获取窗口名称
    13   HWND hProgramWnd =FindWindow(NULL,_T("WindowsName"));
    14   if (hProgramWnd)
    15   {
    16    WINDOWPLACEMENT* pWndpl = NULL;
    17    WINDOWPLACEMENT   wpm; 
    18    
    19    GetWindowPlacement(hProgramWnd,&wpm);
    20    pWndpl =&wpm;
    21    if (pWndpl)
    22    {
    23     //4、将运行的程序窗口还原成正常状态
    24     pWndpl->showCmd = SW_SHOWNORMAL;
    25     SetWindowPlacement(hProgramWnd,pWndpl);
    26     SetWindowPos(hProgramWnd,HWND_NOTOPMOST,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE);
    27     //激活窗口 
    28     SetForegroundWindow(hProgramWnd); 
    29    }
    30   }
    31   //6、关闭进程互斥体
    32   CloseHandle(hMutex);
    33   hMutex = NULL;
    34   return FALSE;
    35  }
    36  return TRUE;
    37 }

    也可以使用下面这种更为简短的代码。但不知为什么,在我的电脑上运行时,感觉上面这段代码比下面代码的运行速度要快很多。

     1 BOOL MyMUTEX()
     2 {
     3  HANDLE hMutex=CreateMutex(NULL,TRUE,_T("Mutex"));
     4  if (hMutex == NULL)
     5  {
     6   return FALSE;
     7  }
     8  if (GetLastError() == ERROR_ALREADY_EXISTS)
     9  {
    10   HWND hProgramWnd =FindWindow(NULL,_T("WindowsName"));
    11   ShowWindow(hProgramWnd,SW_RESTORE);
    12   SetForegroundWindow(hProgramWnd); 
    13  
    14   CloseHandle(hMutex);
    15   hMutex = NULL;
    16   return FALSE;
    17  }
    18  return TRUE;
    19 }
  • 相关阅读:
    不同类型的磁盘存储在Ubuntu下的性能测试
    Ubuntu16.04编译安装Redis Desktop Manager
    gnu screen的用法
    MySQL Workbench常用快捷键
    Libevent例子(二)
    Libevent例子(一)
    Ubuntu下的init.d管理update-rc.d
    Centos7 修改终端文字显示颜色
    通过socks tunnel设置http代理
    linux:C++的socket编程
  • 原文地址:https://www.cnblogs.com/cnstalker/p/4829124.html
Copyright © 2020-2023  润新知