大家好,我想写一个获取进程的小工具,是用tlhelp32的方法进行进程快照.  我的开发环境是VC6.0+xp sp2 具体操作是:在一个对话框里面放了个Button控件,对应的函数叫----OnRefresh(),它的作用是将当前的进程名字、id 及完整路径 放到 对话框里面的 List  Cnotrol控件里面...............本来是没有任何问题的。  但是我提过权之后,再获得 进程路径,就发现,有的进程,如:csrss.exe的路径,就出现乱码:"??C:\windows\system32\csrss.exe"  ,进程路径前多了个问号  这样看着很不舒服,想去掉啊。
  其他进程则没有乱码啊,是正常的。
函数代码如下:void CProcess::OnRefresh() 
{
//显示当前进程的函数,这里是用tlhelp32的方法
HMODULE hMod;   //主模块 HANDLE hProcess;   //进程句柄 char sPath[MAX_PATH];   //进程名字
    DWORD cbNeeded; m_ListCtrl.DeleteAllItems();
HANDLE handle = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);

PROCESSENTRY32* info = new PROCESSENTRY32;

    info->dwSize = sizeof(PROCESSENTRY32);  //这个参数必须指定,规定的

    int i=0;

Process32First(handle,info);
 
do
{

     //从pid来打开进程,获得其句柄,最获得进程路径名     hProcess=OpenProcess( PROCESS_ALL_ACCESS, FALSE, info->th32ProcessID );

     if( EnumProcessModules( hProcess, &hMod, sizeof( hMod ), &cbNeeded ) )  //枚举每个模块,也包括exe,主模块
 {        GetModuleFileNameEx(hProcess, hMod, sPath, MAX_PATH );   //这个函数得到进程的路径名  }
 
 else  strcpy(sPath,"系统进程");
   CloseHandle(hProcess);   //获取路径后, 关闭进程句柄

     CString id;
id.Format("%d",info->th32ProcessID); m_ListCtrl.InsertItem(i,id);   //第i行,第0列

// m_ListCtrl.SetItemText(i,0,id);   //插入pid   要用SetItemData来代替,否则无法取值

m_ListCtrl.SetItemData(i,info->th32ProcessID);

//第i行的第1列,从第1列开始就用这个函数,设置进程名字
m_ListCtrl.SetItemText(i,1,info->szExeFile); 

     //添加进程的路径
 m_ListCtrl.SetItemText(i,2,sPath);
   i++;  //下一行 }while(Process32Next(handle,info)!=FALSE);   //下一个进程
   CloseHandle(handle);  //关闭进程快照       delete info;  //释放内存

}
如何解决乱码的现象???嗨还有 EnumProcessModules   GetModuleFileNameEx  这个函数到底是用来干嘛的???  我看了网上不少资料,大多是转载,复制,这两个个函数资料太少了,查不到,请用中文解释, 英语差,望理解。

解决方案 »

  1.   

    由于csrss.exe 进程有特殊的地位,那个路径不是乱码,而是类似符号链接一类的标记,是正常的,过滤掉就可以了
      

  2.   

    \??\C:\windows\system32\csrss.exe
    这个不是乱码,csrss.exe进程由smss.exe创建,因为smss是native nt程序,不能使用win32 api,使用RtlCreateUserProcess创建csrss.exe进程,这个api使用的文件路径必须是nt路径,c:是一个符号链接,在对象命名空间的GLOBAL??目录中,因此要前面要有\GLOBAL??\或者\??\这样的nt格式路径就会被用来指定csrss.exe进程的exe文件的地方,以及RTL_USER_PROCESS_PARAMETERS中的ImagePathName
      

  3.   

     if( EnumProcessModules( hProcess, &hMod, sizeof( hMod ), &cbNeeded ) ) //枚举每个模块,也包括exe,主模块
    {  GetModuleFileNameEx(hProcess, hMod, sPath, MAX_PATH ); //这个函数得到进程的路径名}
    EnumProcessModules 看他的名字,他的意思是:获得指定的进程的主模块的句柄, 是这样理解吧?不知道我理解对了吗?如果对的话,那么不是还有一个函数:GetModuleHandle("XXX.exe");  这个也是可以获得某dll/exe的句柄。    GetModuleHandle功能和它一样吧?
      

  4.   

    最近在看Windows 核心编程,感觉功力大增了,一起提高吧
      

  5.   

    我也遇到过类似的问题,解决方法是 获得进程的设备路径,GetProcessImageFileName 然后再转换成逻辑路径就能解决这个BUG了。
      

  6.   

    你好刚查看过你提供的那个函数 ,网上是获得诸如:\Device\HarddiskVolume1\... 的路径,我是愚钝不堪,不知道获得后,如何转换为逻辑路径呢??
      

  7.   

    \Device\HarddiskVolume1一般就是\GLOBAL??\C:指向的对象
    符号链接到对象的映射不是单射也不是满射,因此你要查询每个\GLOBAL??\A~Z:对应的对象名,然后比较看是哪几个。你还不如自己处理有\??\的路径