现在的位置: 首页 > 综合 > 正文

判断指定的进程或程序是否存在方法

2017年12月17日 ⁄ 综合 ⁄ 共 4245字 ⁄ 字号 评论关闭
判断指定的进程或程序是否存在方法
分类: 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;   
    }   

抱歉!评论已关闭.