1. 用互斥(Mutex),Mutex本来是多线程同步用的,防止多个线程访问同一资源而引发冲突。用CreateMutex可以创建Mutex对象,实质上是一个kernel对象。
在任何Win32程序(包括GDI和Console)的启动部分加上以下代码(Console程序的main函数、MFC程序的CWinApp派生类的InitInstance成员函数、RawSDK程序的WinMain函数):
hMutex=CreateMutex(
NULL,//nosecurityattributes
FALSE,//initiallynotowned
"RunOnlyOneInstance"); //命名Mutex是全局对象
//在所有的process都可以访问到
if(hMutex==NULL||
ERROR_ALREADY_EXISTS==::GetLastError()) {
//程序第二次或以后运行时,会得到Mutex已经创建的错误
returnFALSE;
}
2.查找窗口,激活。
HWND hOldWnd;
if((hOldWnd=::FindWindow(NULL,_T("志软个人信息管理")))!=NULL)
{
ShowWindow(hOldWnd,SW_RESTORE | SW_SHOWNORMAL);
SetForegroundWindow(hOldWnd);
return FALSE;
}
3.内存映射文件MutexRuning为程序名
初始化阶段:
InitInstance中:
HANDLE hMap=CreateFileMapping((HANDLE)0xffffffff,NULL,PAGE_READWRITE,0,128,
"MutexRuning");
if(hMap==NULL)
{
AfxMessageBox("创建内存映射文件失败",MB_OK|MB_ICONSTOP);
return FALSE;
}
else if(GetLasError()==ERROR_ALREADY_EXISTS)
{
LPVOID lpMem=MapViewOfFile(hMap,FILE_MAP_WRITE,0,0,0);
CString str=(char *)lpMem;
UnmapViewOfile(lpMem);
CloseHandle(hMap);
AfxMessageBox(str,MB_OK|MB_ICONSTOP);
return FALSE;
}
else
{
//是第一次运行
LPVOID lpMem=MapViewOfFile(hMap,FILE_MAP_WRITE,0,0,0);
//程序运行描述信息
strcpy((char*)lpMem, "xxxx正在运行!");
UnmapViewOfFile(lpMem);
}
4.使用原子
BOOL CMainApp::InitInstance()
{
.....
if(GlobalFindAtom("AdBreaker")) //找原子
return false;
ATOM GlobalAtom=GlobalAddAtom("AdBreaker"); //添加原子
CAdBreakerDlg dlg;
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();
.....
GlobalDeleteAtom(GlobalAtom);
return FALSE;
}