您的位置:首页 > 其它

判断指定的进程或程序是否存在方法小结(vc等)

2017-06-28 11:19 686 查看
一、判断指定程序名的进程是否存在
     BOOL EnumWindows( WNDENUMPROC lpEnumFunc, // pointer to callback function LPARAM lParam //   application-defined value); 
       The EnumWindows function enumerates all top-level windows on the screen by passing the handle to each window, in turn, to an application-defined callback function. EnumWindows
continues until the last top-level window is enumerated or the callback function returns FALSE.

复制代码代码如下:

BOOL CALLBACK IpEnumFunc(HWND hwnd,LPARAM lParam)

{

 char wndName[100];

 ::GetWindowText(hwnd,wndName,sizeof(wndName));

 if(wndName!="")

 {

  if(strcmp(wndName,name1)==0)

  {

   WndHnd=hwnd;

   flag=1;

  }

  } 

 return 1;



二、判断指定进程名的进程是否存在

复制代码代码如下:

DWORD GetProcessidFromName(LPCTSTR name)

{

 PROCESSENTRY32 pe;

 DWORD id=0;

 HANDLE hSnapshot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);

 pe.dwSize=sizeof(PROCESSENTRY32);

 if(!Process32First(hSnapshot,&pe))

  return 0;

 while(1)

 {

  pe.dwSize=sizeof(PROCESSENTRY32);

  if(Process32Next(hSnapshot,&pe)==FALSE)

   break;

  if(strcmp(pe.szExeFile,name)==0)

  {

   id=pe.th32ProcessID;

   break;

  }

 }

 CloseHandle(hSnapshot);

 return id;

}

如果返回值不为零,则存在,否则不存在。
三、VC判断程序调用的外部进程是否结束

复制代码代码如下:

PROCESS_INFORMATION pi;

    STARTUPINFO si;

    memset(&si,0,sizeof(si));

    si.cb=sizeof(si);

    si.wShowWindow=SW_HIDE;

    si.dwFlags=STARTF_USESHOWWINDOW;

bool fRet=CreateProcess(NULL,str.GetBuffer(str.GetLength()),NULL,FALSE,NULL,NORMAL_PRIORITY_CLASS   |   CREATE_NO_WINDOW,NULL,NULL,&si,&pi);

///判断

DWORD   ExitCode;   

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));     

  //将取得的进程名与输入的进程名比较,如相同则返回进程PID     

  if(!stricmp(szProcessName, InputProcessName))     

  {     

  CloseHandle(hProcess);     

  return   aProcesses[i];     

  }     

  }     

  }//end   of   if   (hProcess)     

  }//end   of   for     

  //没有找到相应的进程名,返回0     

  CloseHandle(hProcess);     

  return   0;     

  }   

也可以枚举得到所有进程的应用程序名,然后和知道应用程序名比较判断。
五、实现程序只运行一次的方法
        实现程序只运行一次的方法很多,但是原理都是一样的,就是运行第一次的时候设置一个标记,每次运行的时候检查该标记,如果有就说明已经运行了。 
具体实现:
1、在程序初始化的时候   (InitInstance())   枚举所有的窗口,查找本程序的实例是否存在   
2、在主窗口初始化的时候在本窗口的属性列表中添加一个标记,以便程序查找. 
部分关键代码 :
1、在App的InitInstance()中枚举所有窗口,查找本程序实例 

复制代码代码如下:

HWND   oldHWnd   =   NULL; 

EnumWindows(EnumWndProc,(LPARAM)&oldHWnd);  //枚举所有运行的窗口 

if(oldHWnd   !=   NULL) 



AfxMessageBox( "本程序已经在运行了 "); 

::ShowWindow(oldHWnd,SW_SHOWNORMAL);   //激活找到的前一个程序 

::SetForegroundWindow(oldHWnd);       //把它设为前景窗口 

return   false;                       //退出本次运行 



2、添加EnumWndProc窗口过程函数://添加的标识只运行一次的属性名 

复制代码代码如下:

CString   g_szPropName  =  "Your Prop Name ";       //自己定义一个属性名 

HANDLE    g_hValue  =  (HANDLE)1;                   //自己定义一个属性值 

BOOL   CALLBACK   EnumWndProc(HWND   hwnd,LPARAM   lParam) 



HANDLE   h   =   GetProp(hwnd,g_szPropName); 

if(   h   ==   g_hValue) 



*(HWND*)lParam   =   hwnd; 

return   false; 



return   true; 



3、在主窗口的   OnInitDialog()中添加属性   //设置窗口属性 
SetProp(m_hWnd,g_szPropName,g_hValue); 
再次启动时,先检查当前存在的所有窗口,如果有标题相同的,则把先前运行的窗口当成当前窗口 
我的程序如下: 

复制代码代码如下:

HWND   hWnd_Exist; 

hWnd_Exist=::GetDesktopWindow(); 

hWnd_Exist=::GetWindow(hWnd_Exist,GW_CHILD); 

for(;;) 



if(hWnd_Exist==NULL) 



break; 



char   s[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); 

}

声明一个全局   CMutex   变量: 
--------------------------------------------------------------------------------
CMutex   mutexApp(FALSE,   _T( "VPOS2000Server "));   //用此互斥量阻止多个实例 
在你的   CWinApp   类的重载函数:   InitInstance   中加入如下代码:  

复制代码代码如下:

if   (!mutexApp.Lock(1)) 

return   FALSE; 

::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();   

                           return   FALSE;   

                        }   

                        pPrevHwnd   =   pPrevHwnd-> GetWindow(GW_HWNDNEXT);   

                }   

                TRACE( "Could  not  fond  frevious instance main window ! ");   

                return   FALSE;   

        } 

创建一个全局的互斥量,每次启动时检查是否存在。

复制代码代码如下:

BOOL   CRTDBApp::OnlyOneInstance() 



if(::CreateMutex(NULL, TRUE, "onlyone ") == NULL )  

 { 

TRACE0( "CreateMutex   error. "); 

return   FALSE; 

}; 

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(); 

return   FALSE; 



}; 

return   TRUE; 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: