C++ 判断进程是否存在

判断指定的进程或程序是否存在方法  
分类: Windows program 2011-06-27 15:14 112人阅读 评论(0) 收藏 举报  
  
一、判断指定程序名的进程是否存在  
  
     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.  
  
view plain  
  
    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;    
    }     
  
   
  
二、判断指定进程名的进程是否存在  
  
   
  
view plain  
  
    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判断程序调用的外部进程是否结束  
  
   
  
view plain  
  
    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判断进程是否存在?比如我想知道记事本是否运行,要用到哪些函数?  
  
view plain  
  
    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()中枚举所有窗口,查找本程序实例  
  
view plain  
  
    HWND   oldHWnd   =   NULL;     
    EnumWindows(EnumWndProc,(LPARAM)&oldHWnd);  //枚举所有运行的窗口     
    if(oldHWnd   !=   NULL)     
    {     
    AfxMessageBox( "本程序已经在运行了 ");     
    ::ShowWindow(oldHWnd,SW_SHOWNORMAL);   //激活找到的前一个程序     
    ::SetForegroundWindow(oldHWnd);       //把它设为前景窗口     
    return   false;                       //退出本次运行     
    }     
  
   
  
2、添加EnumWndProc窗口过程函数://添加的标识只运行一次的属性名  
  
view plain  
  
    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);  
  
再次启动时,先检查当前存在的所有窗口,如果有标题相同的,则把先前运行的窗口当成当前窗口  
我的程序如下:  
  
view plain  
  
    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   中加入如下代码:   
  
view plain  
  
    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;       
            }     
  
  
创建一个全局的互斥量,每次启动时检查是否存在。  
  
   
  
   
  
view plain  
  
    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;     
    }     

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值