我现在知道一个后台服务进程的名字(没有窗口的进程),在任务管理器中进程中可以看到它.如何在我的程序中判断这个进程是否存在?

解决方案 »

  1.   

    EnumProcesses得到进程ID数组
    OpenProcess得到进程HANDLE
    EnumProcessModules得到该Process的Module数组
    对Module数组的第一个Module调用GetModuleFileNameEx得到exe文件全路径
      

  2.   

    谢谢 akiko(弥弥),我研究一下.
    哪位大侠有现成的代码,贴出来参考一下,下班前要搞出来.先谢谢大家了!!!
      

  3.   

    进程通常被定义为一个正在运行的程序的实例,它由两部分组成:
      <1>操作系统用来管理进程的内核对象。内核对象也是系统用来存放关于进程的统计信息的地方。
      <2>地址空间。它包含所有可执行模块或DLL模块的代码和数据。它还包含动态内存分配的空间,如线程的堆栈和堆分配空间。
      枚举系统进程的实现方法大概有四种,其中有一种可以用来枚举远程NT系统的进程,前提是有远程系统的管理员权限。
    <<第一部分:调用PSAPI函数枚举系统进程>>
      M$的Windows NT开发小组开发了自己Process Status函数,包含在PSAPI.DLL文件中,这些函数只能在高于NT4.0以后的版本中使用。PSAPI一共有14个函数[实际PSAPI.DLL输出函数有19个,但其中有5个函数有两个版本,分别是ANSI和Unicode版本],通过调用这些函数,我们可以很方便的取得系统进程的所有信息,例如进程名、进程ID、父进程ID、进程优先级、映射到进程空间的模块列表等等。为了方便起见,以下的例子程序只获取进程的名字和ID。
      简单的程序如下:
    /*************************************************************************
    Module:ps.c
    说明:调用PSAPI函数枚举系统进程名和ID,Only for NT/2000
    *************************************************************************/
    #include 
    #include 
    #include "psapi.h"#pragma comment(lib,"psapi.lib")
    void PrintProcessNameAndID( DWORD processID )
    {  char szProcessName[MAX_PATH] = "unknown";  //取得进程的句柄  HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |                  PROCESS_VM_READ,                  FALSE, processID );  //取得进程名称  if ( hProcess )  {    HMODULE hMod;    DWORD cbNeeded;    if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod), &cbNeeded) )      GetModuleBaseName( hProcess, hMod, szProcessName,sizeof(szProcessName) );  }  //回显进程名称和ID  printf( "\n%-20s%-20d", szProcessName, processID );//这儿都有szProcessName了知道怎么作了吧,呵呵。
      CloseHandle( hProcess );}void main( ){  DWORD aProcesses[1024], cbNeeded, cProcesses;  unsigned int i;  //枚举系统进程ID列表  if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )    return;  // Calculate how many process identifiers were returned.  //计算进程数量  cProcesses = cbNeeded / sizeof(DWORD);  // 输出每个进程的名称和ID  for ( i = 0; i < cProcesses; i++ )    PrintProcessNameAndID( aProcesses[i] );  return;}
      

  4.   

    第二种:
     首先, 调用 CreateToolhelp32Snapshot() 获得当前运行进程的快照,这个函数返回包含正在运行进程的快照句柄。其原形是:HANDLE WINAPI CreateToolhelp32Snapshot(DWORD dwFlags,DWORD th32ProcessID);其中:
    dwFlags表示要包含在快照的内容为TH32CS_SNAPPROCESS表示在快照中包含进程列表;
    th32ProcessID是进程号,为0表示当前进程。
    返回值是一个句柄,如果没有进程正在运行,则返回INVALID_HANDLE_VALUE(可用GetLastError()获得),反之可用BOOL WINAPI Process32First(HANDLE hSnapshot, LPPROCESSENTRY32 lppe);获取返回的进程
    如果Process32First返回TRUE,则第一个进程的信息已经在LPPROCESSENTRY32结构中,其余进程信息可用BOOL WINAPI Process32Next(HANDLE hSnapshot, LPPROCESSENTRY32 lppe)获得
    LPPROCESSENTRY32结构的定义如下: typedef struct tagPROCESSENTRY32 { 
      DWORD dwSize; //此结构的大小
      DWORD cntUsage; //进程的引用数,如果为0,则次进程已停止
      DWORD th32ProcessID; //进程号
      ULONG_PTR th32DefaultHeapID; 
      DWORD th32ModuleID; //此进程引用的模块ID
      DWORD cntThreads; //此进程创建的线程数
      DWORD th32ParentProcessID; //父进程的ID
      LONG  pcPriClassBase; //这个进程创建的线程的基本优先权
      DWORD dwFlags; //保留
      TCHAR szExeFile[MAX_PATH]; 
    } PROCESSENTRY32; 
    typedef PROCESSENTRY32 *PPROCESSENTRY32;       
    最后不要忘了调用:  CloseHandle();      
    另用函数是: HANDLE OpenProcess(
      DWORD dwDesiredAccess,  // access flag
      BOOL bInheritHandle,    // handle inheritance option
      DWORD dwProcessId       // process identifier
    );     
    用它可打开一个进程,打开进程后,可用: BOOL TerminateProcess(
      HANDLE hProcess, // handle to the process
      UINT uExitCode   // exit code for the process
    );      
        
      

  5.   

    EnumProcesses,EnumProcessModules,GetModuleBaseName没有定义.我用的是vc6.0,win2k
    psapi.h和psapi.lib都是.net才有的.这两个文件我有.但怎么才能在vc6.0下使用?
      

  6.   

    第三种方法:调用ToolHelp API枚举本地系统进程(针对WIN9X系统)
    在第一部分提到的PSAPI函数只能枚举NT系统的进程,在Windows9x环境下我们可以通过调用ToolHelp API函数来达到枚举系统进程的目的。M$的Windows NT开发小组因为不喜欢ToolHelp函数,所以没有将这些函数添加给Windows NT,所以他们开发了自己的Process Status函数,就是第一部分提到的PSAPI了。但是后来M$已经将ToolHelp函数添加给了Windows 2000。ToolHelp共有12个函数,通过调用这些函数可以方面的取得本地系统进程的详细信息,以下这个简单的例子只调用了三个函数,获取我们所需要系统进程名字和进程ID。程序如下:
    /**********************************************************************
    Module:ps.c
    说明:调用ToolHelp函数枚举本地系统进程名和ID,Only for 9x/2000
    **********************************************************************/
    #include 
    #include 
    #include 
    int main()
    {
      HANDLE     hProcessSnap = NULL;
      PROCESSENTRY32 pe32   = {0};
      hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
      if (hProcessSnap == (HANDLE)-1)
      {
       printf("\nCreateToolhelp32Snapshot() failed:%d",GetLastError());
      return 1;
    }
      pe32.dwSize = sizeof(PROCESSENTRY32);
      printf("\nProcessName     ProcessID");
      if (Process32First(hProcessSnap, &pe32))
      {
       do
        {
    printf("\n%-20s%d",pe32.szExeFile,pe32.th32ProcessID);
         }while (Process32Next(hProcessSnap, &pe32));
      }
      else
      {
       printf("\nProcess32Firstt() failed:%d",GetLastError());
      }
      CloseHandle (hProcessSnap);
    return 0;}
    第四:调用NTDLL.DLL中未公开API枚举本地系统进程
    那个未公开API就是NtQuerySystemInformation
    第五部分:从PDH中取得本地/远程系统进程信息
    先简单的说说PDH是什么东西,PDH是英文Performance Data Helper的缩写,Windows NT一直在更新这个称为Performance Data的数据库,这个数据库包含了大量的信息,例如CPU使用率,内存使用率,系统进程信息等等一大堆有用的信息,可以通过注册表函数来访问。注意哦,Windows 9x中并没有配置这个数据库。但是,这个数据库中的信息布局很复杂,很多人并不愿意使用它,包括我。而且刚开始的时候,它也没有自己特定的函数,只能通过现有的注册表函数来操作。后来,为了使该数据库的使用变得容易,MS开发了一组Performance Data Helper函数,包含在PDH.DLL文件中。Windows 2000默认是允许远程注册表操作的,所以我们就可以通过连接远程系统的注册表,从它的PDH中取得我们所需要的系统进程信息了,当然这需要远程系统的Admin权限。
    只可惜不能再贴代码了,满了,不让贴
      

  7.   

    To yintongshun(踏雪有痕):你说的两种方法我都照MSDN上的源码试了.我装的是vc6.0,MSDN2002结果EnumProcesses,EnumProcessModules,GetModuleBaseName这三个函数不能用.
    第二种方法是编译过去了,但是GetProcessModule(DWORD dwPID, DWORD dwModuleID, LPMODULEENTRY32 lpMe32, DWORD cbMe32)总是返回0
    请帮忙,谢谢!
      

  8.   

    我把.net的psapi.lib链接进去用了.第一种方法能列举出进程. 
    不过出现很严重的问题.只要不是.exe结尾的进程,全部提示unknown,为什么?
    例如System Idle Process 和 System都提示为unknown
      

  9.   

    直接
    LoadLibrary("C:\\WINNT\\system32\\psapi.dll");
    通过GetProcAddress得到
    EnumProcesses
    EnumProcessModules
    GetModuleFileNameEx
    三个函数指针
      

  10.   

    #include "winperf.h"
    #include <tlhelp32.h>typedef HANDLE (WINAPI *PFN_CREATETHELP32SNPSHT)(DWORD,DWORD); 
    typedef BOOL (WINAPI *PFN_PROCESS32FIRST)(HANDLE,PROCESSENTRY32*); 
    typedef BOOL (WINAPI *PFN_PROCESS32NEXT)(HANDLE,PROCESSENTRY32*); 
    HMODULE m_hWin95Kernel;
    PFN_PROCESS32NEXT m_p_fnProcess32Next;
    PFN_PROCESS32FIRST m_p_fnProcess32First;
    PFN_CREATETHELP32SNPSHT m_p_fnCreateToolhelp32Snapshot;

    m_hWin95Kernel=GetModuleHandle(_T("kernel32.dll"));
    if(!m_hWin95Kernel)
    {
    m_strLastError=_T("Could not get kernel32 handle");
    return false;
    }
    m_p_fnCreateToolhelp32Snapshot=(PFN_CREATETHELP32SNPSHT)GetProcAddress(m_hWin95Kernel,"CreateToolhelp32Snapshot");
    if (!m_p_fnCreateToolhelp32Snapshot)
    {
    m_strLastError=_T("Could not get CreateToolhelp32Snapshot pointer");
    return false;
    } m_p_fnProcess32First=(PFN_PROCESS32FIRST)GetProcAddress(m_hWin95Kernel,"Process32First");
    if (!m_p_fnProcess32First)
    {
    m_strLastError=_T("Could not get Process32First pointer");
    return false;
    } m_p_fnProcess32Next=(PFN_PROCESS32NEXT)GetProcAddress(m_hWin95Kernel,"Process32Next");
    if (!m_p_fnProcess32Next)
    {
    m_strLastError=_T("Could not get Process32Next pointer");
    return false;
    }
    //获得函数指针bool Win32Process::FindProcesses95(CString* ProcessName, bool bJustCheckingOne)
    {
    ///This function gets all the running process, the win95 way, using the
    ///ToolHelp functions. If you simply are checking if a process is active
    ///pass its name as a parameter and make the second parameter false.
    ///Otherwise, the function will ignore the ProcessName param and add to the array
    ///all the currently active processes...
    ASSERT(m_p_fnProcess32Next);
    ASSERT(m_p_fnProcess32First);
    ASSERT(m_p_fnCreateToolhelp32Snapshot);    ///must have successfully called Init() first if (!bJustCheckingOne)
    {
    m_strArray.RemoveAll();
    }
    else
    {
    m_bActive=false;
    ASSERT ((*ProcessName)!=""); ///If just checking if a process is alive, this must be the process' name
    }
    HANDLE handle;
    handle=m_p_fnCreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
    if ((const int)handle==-1)
    {
    m_strLastError=_T("Failed in creating snapshot");
    return false;
    } PROCESSENTRY32 process;
    process.dwSize=sizeof(PROCESSENTRY32); BOOL bContinue=m_p_fnProcess32First(handle,&process); while(bContinue)
    {
    if (!bJustCheckingOne) //do we want to enumerate all processes, or do we just wanna check if one is active?
    m_strArray.Add(ExtractProcessName(process.szExeFile));
    else
    {
    ///if here, then we are just looking to see if a certain process is alive...
    if ((*ProcessName) == ExtractProcessName(process.szExeFile))
    {
    ///found the process, it is active....
    CloseHandle(handle);
    m_bActive=true;
    return true;
    }
    }
    bContinue=m_p_fnProcess32Next(handle,&process);
    } CloseHandle(handle);
    return true;
    }