一、判断指定程序名的进程是否存在BOOLEnumWindows(WNDENUMPROClpEnumFunc,//pointertocallbackfunctionLPARAMlParam//application-definedvalue);TheEnumWindowsfunctionenumeratesalltop-levelwindowsonthescreenbypassingthehandletoeachwindow,inturn,toanapplication-definedcallbackfunction.EnumWindowscontinuesuntilthelasttop-levelwindowisenumeratedorthecallbackfunctionreturnsFALSE.
BOOLCALLBACKIpEnumFunc(HWNDhwnd,LPARAMlParam){charwndName[100];::GetWindowText(hwnd,wndName,sizeof(wndName));if(wndName!=""){if(strcmp(wndName,name1)==0){WndHnd=hwnd;flag=1;}}return1;}二、判断指定进程名的进程是否存在
DWORDGetProcessidFromName(LPCTSTRname){PROCESSENTRY32pe;DWORDid=0;HANDLEhSnapshot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);pe.dwSize=sizeof(PROCESSENTRY32);if(!Process32First(hSnapshot,&pe))return0;while(1){pe.dwSize=sizeof(PROCESSENTRY32);if(Process32Next(hSnapshot,&pe)==FALSE)break;if(strcmp(pe.szExeFile,name)==0){id=pe.th32ProcessID;break;}}CloseHandle(hSnapshot);returnid;}如果返回值不为零,则存在,否则不存在。三、VC判断程序调用的外部进程是否结束
PROCESS_INFORMATIONpi;STARTUPINFOsi;memset(&si,0,sizeof(si));si.cb=sizeof(si);si.wShowWindow=SW_HIDE;si.dwFlags=STARTF_USESHOWWINDOW;boolfRet=CreateProcess(NULL,str.GetBuffer(str.GetLength()),NULL,FALSE,NULL,NORMAL_PRIORITY_CLASS|CREATE_NO_WINDOW,NULL,NULL,&si,&pi);///判断DWORDExitCode;ExitCode=STILL_ACTIVE;while(ExitCode==STILL_ACTIVE){GetExitCodeProcess(pi.hProcess,&ExitCode);}四、VC判断进程是否存在?比如我想知道记事本是否运行,要用到哪些函数?
enProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,FALSE,aProcesses[i]);//取得特定PID的进程名if(hProcess){if(EnumProcessModules(hProcess,&hMod,sizeof(hMod),&cbNeeded)){GetModuleBaseName(hProcess,hMod,szProcessName,sizeof(szProcessName));//将取得的进程名与输入的进程名比较,如相同则返回进程PIDif(!stricmp(szProcessName,InputProcessName)){CloseHandle(hProcess);returnaProcesses[i];}}}//endofif(hProcess)}//endoffor//没有找到相应的进程名,返回0CloseHandle(hProcess);return0;}也可以枚举得到所有进程的应用程序名,然后和知道应用程序名比较判断。五、实现程序只运行一次的方法实现程序只运行一次的方法很多,但是原理都是一样的,就是运行第一次的时候设置一个标记,每次运行的时候检查该标记,如果有就说明已经运行了。具体实现:1、在程序初始化的时候(InitInstance())枚举所有的窗口,查找本程序的实例是否存在2、在主窗口初始化的时候在本窗口的属性列表中添加一个标记,以便程序查找.部分关键代码:1、在App的InitInstance()中枚举所有窗口,查找本程序实例
HWNDoldHWnd=NULL;EnumWindows(EnumWndProc,(LPARAM)&oldHWnd);//枚举所有运行的窗口if(oldHWnd!=NULL){AfxMessageBox("本程序已经在运行了");::ShowWindow(oldHWnd,SW_SHOWNORMAL);//激活找到的前一个程序::SetForegroundWindow(oldHWnd);//把它设为前景窗口returnfalse;//退出本次运行}
2、添加EnumWndProc窗口过程函数://添加的标识只运行一次的属性名
CStringg_szPropName="YourPropName";//自己定义一个属性名HANDLEg_hValue=(HANDLE)1;//自己定义一个属性值BOOLCALLBACKEnumWndProc(HWNDhwnd,LPARAMlParam){HANDLEh=GetProp(hwnd,g_szPropName);if(h==g_hValue){*(HWND*)lParam=hwnd;returnfalse;}returntrue;}
3、在主窗口的OnInitDialog()中添加属性//设置窗口属性SetProp(m_hWnd,g_szPropName,g_hValue);再次启动时,先检查当前存在的所有窗口,如果有标题相同的,则把先前运行的窗口当成当前窗口我的程序如下:
HWNDhWnd_Exist;hWnd_Exist=::GetDesktopWindow();hWnd_Exist=::GetWindow(hWnd_Exist,GW_CHILD);for(;;){if(hWnd_Exist==NULL){break;}chars[256];memset(s,0,256);::SendMessage(hWnd_Exist,WM_GETTEXT,255,(LONG)s);if(strstr(s,"******")!=NULL)break;hWnd_Exist=::GetWindow(hWnd_Exist,GW_HWNDNEXT);}if(hWnd_Exist!=NULL){::ShowWindow(hWnd_Exist,SW_SHOWNORMAL);::SetForegroundWindow(hWnd_Exist);exit(0);}
if(!mutexApp.Lock(1))returnFALSE;::CreateMutex(NULL,TRUE,m_pszExeName);if(ERROR_ALREADY_EXISTS==GetLastError()){CWnd*pPrevHwnd=CWnd::GetDesktopWindow()->GetWindow(GW_CHILD);while(pPrevHwnd){if(::GetProp(pPrevHwnd->GetSafeHwnd(),m_pszExeName)){if(pPrevHwnd->IsIconic()){pPrevHwnd->ShowWindow(SW_RESTORE);}pPrevHwnd->SetForegroundWindow();pPrevHwnd->GetLastActivePopup()->SetForegroundWindow();returnFALSE;}pPrevHwnd=pPrevHwnd->GetWindow(GW_HWNDNEXT);}TRACE("Couldnotfondfreviousinstancemainwindow!");returnFALSE;}
创建一个全局的互斥量,每次启动时检查是否存在。
BOOLCRTDBApp::OnlyOneInstance(){if(::CreateMutex(NULL,TRUE,"onlyone")==NULL){TRACE0("CreateMutexerror.");returnFALSE;};if(::GetLastError()==ERROR_ALREADY_EXISTS){CWnd*pPrevWnd=CWnd::FindWindow(NULL,"onlyonehwnd");if(pPrevWnd){if(pPrevWnd->IsIconic())pPrevWnd->ShowWindow(SW_RESTORE);pPrevWnd->SetForegroundWindow();pPrevWnd->GetLastActivePopup()->SetForegroundWindow();returnFALSE;}};returnTRUE;}