大家好,我想写一个获取进程的小工具,是用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 这个函数到底是用来干嘛的??? 我看了网上不少资料,大多是转载,复制,这两个个函数资料太少了,查不到,请用中文解释, 英语差,望理解。
其他进程则没有乱码啊,是正常的。函数代码如下: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 这个函数到底是用来干嘛的??? 我看了网上不少资料,大多是转载,复制,这两个个函数资料太少了,查不到,请用中文解释, 英语差,望理解。
这个不是乱码,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
{ GetModuleFileNameEx(hProcess, hMod, sPath, MAX_PATH ); //这个函数得到进程的路径名}
EnumProcessModules 看他的名字,他的意思是:获得指定的进程的主模块的句柄, 是这样理解吧?不知道我理解对了吗?如果对的话,那么不是还有一个函数:GetModuleHandle("XXX.exe"); 这个也是可以获得某dll/exe的句柄。 GetModuleHandle功能和它一样吧?
符号链接到对象的映射不是单射也不是满射,因此你要查询每个\GLOBAL??\A~Z:对应的对象名,然后比较看是哪几个。你还不如自己处理有\??\的路径