簡介
在我們編寫程序的時候,經(jīng)常會注意到的一個問題就是如何能夠讓程序只運(yùn)行一個實例铁瞒,確保不會讓同一個程序多次運(yùn)行貌笨,從而產(chǎn)生諸多相同進(jìn)程,給我們的帶來不便呢绑青?那么常用的有以下四種方法诬像,第一種方法是通過掃描進(jìn)程列表比對進(jìn)程名來檢測,第二種方法是通過枚舉程序窗口的方式闸婴,第三種方法是采用共享全局變量來實現(xiàn)坏挠,第四種方法是通過創(chuàng)建互斥體來實現(xiàn)。
那么在這些方法中邪乍,第一種和第二種方法是有缺陷的降狠,掃描進(jìn)程列表比對進(jìn)程名容易對相同進(jìn)程名字的不同程序產(chǎn)生誤報,枚舉窗口不適用于無窗口程序且與掃描進(jìn)程列表的方法也有相同的缺陷溺欧。所以本文筆者為大家介紹第三種方法與第四種方法的具體實現(xiàn)喊熟。
代碼實現(xiàn)
1. 互斥體實現(xiàn)方式
//////////////////////////////////////////////////////////////////
//
// FileName : SingleRunByMutex.cpp
// Creator : PeterZheng
// Date : 2019/2/16 11:21
// Comment : 互斥體實現(xiàn)進(jìn)程單實例運(yùn)行
//
//////////////////////////////////////////////////////////////////
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <Windows.h>
using namespace std;
// 使用互斥體保證單體運(yùn)行
BOOL IsAlreadyRun()
{
HANDLE hMutex = NULL;
hMutex = CreateMutex(NULL, FALSE, "MYFLAG");
if (hMutex != NULL)
{
if (ERROR_ALREADY_EXISTS == GetLastError())
{
ReleaseMutex(hMutex);
return TRUE;
}
}
return FALSE;
}
// 主函數(shù)
int APIENTRY WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd)
{
if (IsAlreadyRun())
{
MessageBox(NULL, "This Program is already RUN !", "Tips", MB_OK);
}
else
{
MessageBox(NULL, "I am RUN !", "Tips", MB_OK);
Sleep(30000);
}
ExitProcess(0);
return 0;
}
2. 共享全局變量實現(xiàn)方式
//////////////////////////////////////////////////////////////////
//
// FileName : SingleRunByShareSeg.cpp
// Creator : PeterZheng
// Date : 2019/2/16 11:40
// Comment : 通過共享全局變量的方式實現(xiàn)進(jìn)程單實例運(yùn)行
//
//////////////////////////////////////////////////////////////////
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <Windows.h>
using namespace std;
// 創(chuàng)建共享內(nèi)存段
#pragma data_seg("sharedata")
DWORD dwFlagId = 0xEE;
#pragma data_seg()
#pragma comment(linker, "/SECTION:sharedata,RWS")
// 使用共享內(nèi)存段保證單體運(yùn)行
BOOL IsAlreadyRun()
{
if (dwFlagId == 0xEF)
{
return TRUE;
}
return FALSE;
}
// 主函數(shù)
int APIENTRY WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd)
{
if (IsAlreadyRun())
{
MessageBox(NULL, "This Program is already RUN !", "Tips", MB_OK);
}
else
{
MessageBox(NULL, "I am RUN !", "Tips", MB_OK);
dwFlagId = 0xEF;
Sleep(30000);
}
ExitProcess(0);
return 0;
}