实例总结:查看虚拟内存状态

来源:互联网 发布:猎场网络什么时候播出 编辑:程序博客网 时间:2024/06/05 20:43

本文主要是对完成的实例的一个总结,由于长时间不接触,涉及到一些技术细节记录下来。

一、对话框之间的消息传递,实现数据传递

::SendMessage(this->GetParent()->m_hWnd, WM_C_SELECT_PROCESS, WPARAM(), LPARAM(relatedID.GetBuffer()));

或者:

this->GetParent()->SendMessage(WM_C_SELECT_PROCESS, WPARAM(), LPARAM(relatedID.GetBuffer()));

在使用GetBuffer()后,需要配对使用函数:relatedID.ReleaseBuffer(); [参考:GetBuffer()与ReleaseBuffer()的用法,CString]

而消息响应类中,仅需要:

BEGIN_MESSAGE_MAP(CMenmoryViewToolDlg, CDialogEx)    ON_MESSAGE(WM_C_SELECT_PROCESS, OnCustomSelectProcess)END_MESSAGE_MAP()

二、CListCtrl按列排序问题 

本实例中并没有涉及到点击列标题排序,只实现按指定列排序。[CListCtrl 使用详细] 需要以下步骤:

  • 实现回调的比较函数static int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)

int CALLBACK SelectPrcDlg::CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort){UNREFERENCED_PARAMETER(lParamSort);CListCtrl* pListCtrl = (CListCtrl*)lParamSort;CString strItem1((LPWSTR)lParam1);CString strItem2((LPWSTR)lParam2);return wcscmp(strItem1, strItem2);}

  • 设置列表项Item的Data,this->m_list.SetItemData(j, LPARAM(lpwstr[j]->GetBuffer())); 即LVITEM structure中的LPARAM lParam [LVITEM] ;需要注意的是,如果设置的值(作比较的值)是字符串的话,需要设置为指向堆上的指针,否则回调时会访问到非法内存(无意义);
  • 调用m_list.SortItems(&SelectPrcDlg::CompareFunc, 0);第二个参数,即回调函数的最后一个参数LPARAM lParamSort;

三、打开进程OpenProcess

打开进程失败,通过GetLastError()获取ErrorCode,=5时代表ERROR_ACCESS_DENIED,Access is denied。可能的原因是权限不够,可以尝试提升权限(工程设置、修改程序启动权限或者通过代码修改)。还可能是编译为win32程序,x64系统上试图打开64位程序,也会失败。另外,几个系统进程例如smss.exe、系统中断等无权访问,也会打开失败。

打开失败无法获取程序句柄,通过EnumProcesses()枚举进程无法获取程序名称,而通过进程快照的方式可获得PID对应的程序名:

PROCESSENTRY32 pe32;pe32.dwSize = sizeof(pe32);// 在使用这个结构之前,先设置它的大小  // 给系统内的所有进程拍一个快照  HANDLE hProcessSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);if (hProcessSnap == INVALID_HANDLE_VALUE){printf(" CreateToolhelp32Snapshot调用失败! \n");return FALSE;}// 遍历进程快照,轮流显示每个进程的信息  BOOL bMore = ::Process32First(hProcessSnap, &pe32);while (bMore){this->GetProcessInfo(pe32.th32ProcessID, pe32.szExeFile);<span style="white-space:pre"></span>// 该函数在后文bMore = ::Process32Next(hProcessSnap, &pe32);}// 不要忘记清除掉snapshot对象  ::CloseHandle(hProcessSnap);

根据PID获取进程信息的代码(逻辑操作是将信息列入CListCtrl内):

VOID SelectPrcDlg::GetProcessInfo(DWORD pid, CString processName){int index = this->m_list.GetItemCount();HMODULE hMods[MAX_CLASS_NAME] = { 0 };DWORD cbNeededModule = 0;WCHAR szModuleName[MAX_CLASS_NAME] = { 0 };PROCESS_MEMORY_COUNTERS ProcessMemCounters;// 通过进程ID打开进程HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);if (hProcess == NULL){CString cstrFailed;DWORD dwErr = GetLastError();cstrFailed.AppendFormat(L"访问[%s]失败,ErrorCode::%d ", processName, dwErr);wcscpy_s(szModuleName, cstrFailed);}if (hProcess != NULL){// 枚举进程模块信息::EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeededModule);// 取得主模块名称,即进程名::GetModuleFileNameEx(hProcess, hMods[0], szModuleName, sizeof(szModuleName));// 取得进程的内存使用信息::GetProcessMemoryInfo(hProcess, &ProcessMemCounters, sizeof(ProcessMemCounters));// 获取进程PID//cbPid = ::GetProcessId(hProcess);// 关闭进程句柄CloseHandle(hProcess);}// 显示结果CString cstrProcess;cstrProcess.AppendFormat(L"[%d]", pid);this->m_list.InsertItem(index, cstrProcess);this->m_list.SetItemText(index, 1, szModuleName);m_dataBuffer[index] = new struct _Data;m_dataBuffer[index]->szModuleName = szModuleName;m_dataBuffer[index]->dwProcessId = pid;this->m_list.SetItemData(index, LPARAM(m_dataBuffer[index]));return;}

四、访问指定进程内存信息

  • CEdit显示等宽字体和复选框状态问题:

HFONT hFont = (HFONT)::GetStockObject(SYSTEM_FIXED_FONT);CFont *pFont = CFont::FromHandle(hFont);m_edit.SetFont(pFont);<span style="white-space:pre">((CButton*)this->GetDlgItem(IDC_CHECK1))->SetCheck(BST_CHECKED);</span>
  • 64位程序指针长度为8Byte,cstrTemp.Format(L"%08X", m_systemInfo.dwPageSize);,m_systemInfo类型为SYSTEM_INFO;这里无论%0nX的n是多少,结果字符串不会显示全部,如0x00007FFFFFFFEFFFF,这里最多只会显示到 “FFFEFFFF”,具体原因还没有找到,欢迎留言或者私信指教,感谢~。
  • 64位程序(当然在64位系统上)的m_systemInfo.lpMinimumApplicationAddress = 0x0000000000010000m_systemInfo.lpMaximumApplicationAddress = 0x00007FFFFFFFEFFFF(在我机器上),当我循环获取内存信息时惊觉,这段内存(进程空间,虚拟内存)非常大,根本没法循环遍历。这个问题在编译为位程序时并不存在。这个实例到此暂时停下,需要去研究研究x64和x86的架构了。这里该如何处理,还欢迎指教~

0 0
原创粉丝点击