最近项目开发过程中遇到了保证程序只有一个实例存在的需求,也就是只能存在一个exe。本人目前有两种实现的方法。
一、基于Qt的实现
基于Qt的实现是利用了Qt中的共享内存(QSharedMemory),第一个运行的exe创建一个共享内存,后续的程序如果能访问到此内存,就认为已有exe存在了。伪代码如下:
int main()
{
//创建一个共享内存
QSharedMemory sharedMemory;
//设置共享内存的标识,这个标识是确定的
sharedMemory.setKey(strPid);
//尝试去attach由标识符指定的内存块,如果attach成功
//说明这个内存段已经存在了,也就是说已经存在一个exe了那么就可以
if (m_sharedMemory.attach())
{
m_bRunning = true;
return;
}
else
{
m_bRunning = false;
//运行到此,说明还不存在exe,创建一个大小为1的共享内存段
if (!m_sharedMemory.create(1))
{
m_bRunning = true;
}
}
}
二、基于C++的实现
这里是针对windows平台,基于windows的接口实现。是根据名称去查找进程数量,然后进行处理。
//根据进程名称查找进程数量是否大于1 bool testOpenProcess::findProcessIdAccordName(const std::string& proName, QVector& proId) { int i = 0; PROCESSENTRY32 pe32; pe32.dwSize = sizeof(pe32); HANDLE hProcessSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (hProcessSnap == INVALID_HANDLE_VALUE) { i += 0; } BOOL bMore = ::Process32First(hProcessSnap, &pe32); while (bMore) { char ansi[512] = { 0 }; WideCharToMultiByte(CP_ACP, 0, pe32.szExeFile, -1, ansi, sizeof(ansi), NULL, NULL); std::string path = ansi; std::string appName = proName; if (stricmp(appName.c_str(), ansi) == 0) { //printf("进程运行中"); i += 1; proId.push_back(pe32.th32ProcessID); printf("findProcessByName: find a same name exe:%s n", path.c_str()); //break; } //printf(" 进程名称:%s ;saved app name is %sn", path.c_str(), appName.toStdString().c_str()); bMore = ::Process32Next(hProcessSnap, &pe32); } ::CloseHandle(hProcessSnap); if (i > 1) { //数量大于1,说明排除自身外,还存在一个同名进程,说明自己不是第一个 printf("findProcessByName : find a exe in taskn"); return true; } else { //printf("findProcessByName : not find a exe in taskn"); return false; } } int main() { QVector appID; if (findProcessIdAccordName("testOpenProcess.exe", appID)) { return; } //...后续操作 }



