WINCE程序单实例运行

    技术2024-04-19  16

       Wince下开发应用程序时很多情况下需要让程序只能有一个实例运行,实现方法主要是在程序入口点检查当前实例是否正在运行,如实例已运行,则退出本次执行。总结了一下,主要有以下三种方式:

    1.通过FindWindow查找指定窗口是否存在,参考代码如下:

    // 查找是否有实例运行 HWND hExistWnd = ::FindWindow(NULL,_T("WindowName")); if (!hExistWnd) { printf("The app is already running...../n"); return FALSE; }

          此种方式只限于有窗口的程序,对于无窗口程序或者指定窗口还未创建但实例已经存在的程序就无效了。一个更好的方法是通过内核对象---定义一个互斥体来实现。

    2.通过定义一个互斥体来确保只有一个实例运行,参考代码如下:

    // 定义一个互斥体,确保程序只有一个实例在运行 HANDLE hMutex=CreateMutex(NULL, FALSE, _T("WindowName")); if(!hMutex) { printf("Failed to CreateMutex().../n") return FALSE; } if(ERROR_ALREADY_EXISTS == GetLastError()) { printf("The app is already running.../n"); CloseHandle(hMutex); return FALSE; }

    3.全局原子方法,在程序入口点检查指定原子是否存在,若存在则退出程序,若不存在,则在系统原子表中添加原子,用以记录当前实例正在运行,并在程序退出之前删除改原子,表示该实例已退出。参考代码如下

    // 全局原子 ATOM g_AtomRAS=0; // 程序入口点检查原子是否存在 if (GlobalFindAtom(_T("AtomName"))) { printf("The app is already running.../n"); return FALSE; } else { // 创建原子 g_AtomRAS=GlobalAddAtom(_T("AtomName")); }

         记得在程序退出时将原子删除// 删除全局原子 GlobalDeleteAtom(g_AtomRAS);

            采用全局原子的方法相当于是在系统原子表中记录了程序运行的两种状态:运行状态和非运行状态。新实例在启动时通过查找原子的存在与否来判断程序处于何种状态,但需要注意一点的是:有些程序在退出的时候由于需要卸载组件释放资源,但这个过程可能需要一定的时间。如果这个时候运行程序的另一个实例,由于之前程序还在运行,根据单实例原则这个新实例会立即退出,而之前实例在资源卸载完后也会立即退出。这样就会造成两个程序都退出了。所以对于这样的程序,就需要记录另外一种状态:退出状态,这样新的实例在启动时能够知道当前实例是否正在退出,若正在退出,则继续运行当前实例。

            所以可以在原子表中另外定义一个原子来表示程序处在退出状态。在窗口WM_DESTROY消息处理中添加以下代码:

    case WM_DESTROY: // 添加原子,记录程序处于退出状态 g_AtomRAS=GlobalAddAtom(_T("AppClosing")); // 卸载资源 // TODO:place code here // 删除原子 GlobalDeleteAtom(_T("AppClosing")) PostQuitMessage(0); break;

          在程序入口时候判断是否有实例运行,有则继续判断实例是否正在退出,从而对三种状态分别做不同处理。参考代码如下:

    // 定义一个互斥体,确保程序只有一个实例在运行 HANDLE hMutex=CreateMutex(NULL, FALSE, _T("WindowName")); if(!hMutex) { printf("Failed to CreateMutex().../n") return FALSE; } if(ERROR_ALREADY_EXISTS == GetLastError()) { if(GloalFindAtom(_T("AppClosing"))) { // 程序正在退出 printf("The app is closing.../") } else { // 程序正在运行 printf("The app is already running.../n"); CloseHandle(hMutex); return FALSE; } } // 没有正在运行的实例 .....

     

     

    最新回复(0)