/// <summary> /// Retrieves the thread Ids, starting address, and priority level of /// the specified process. /// </summary> private void GetThreadDetails(int pid) { const NativeMethods.SnapshotFlags flags = NativeMethods.SnapshotFlags.TH32CS_SNAPTHREAD; var hModuleSnap = NativeMethods.CreateToolhelp32Snapshot(flags, pid); if (hModuleSnap == INVALID_HANDLE_VALUE) { return; } var threadEntry = new NativeMethods.THREADENTRY32 { dwSize = (uint)Marshal.SizeOf(typeof(NativeMethods.THREADENTRY32)), cntUsage = 0 }; if (!NativeMethods.Thread32First(hModuleSnap, ref threadEntry)) { NativeMethods.CloseHandle(hModuleSnap); return; } do { if (threadEntry.th32OwnerProcessID == pid) { var lvi = new ListViewItem(threadEntry.th32ThreadID.ToString()); var address = (long)GetThreadStartAddress(threadEntry.th32ThreadID); var priority = string.Empty; lvi.SubItems.Add(GetThreadStartAddress(ParentProcess, address)); switch (threadEntry.tpBasePri) { case 1: priority = "Idle"; break; case 6: priority = "Lowest"; break; case 7: priority = "Below Normal"; break; case 8: priority = "Normal"; break; case 9: priority = "Above Normal"; break; case 10: priority = "Highest"; break; case 15: priority = "Time Critical"; break; } lvi.SubItems.Add(priority /* + " (" + threadEntry.tpBasePri + ")" */); LV_Thread.Items.Add(lvi); } }while (NativeMethods.Thread32Next(hModuleSnap, ref threadEntry)); // Close the object NativeMethods.CloseHandle(hModuleSnap); LV_Thread.Sorting = SortOrder.Ascending; threadCount = LV_Thread.Items.Count; SetThreadCount(); }
/// <summary> /// Retrieves the names of all loaded modules in the process, their base /// address and size on disk. /// </summary> /// /// <param name="pid"> /// Id of the process. /// </param> private void GetModuleDetails(int pid) { const NativeMethods.SnapshotFlags flags = NativeMethods.SnapshotFlags.TH32CS_SNAPMODULE | NativeMethods.SnapshotFlags.TH32CS_SNAPMODULE32; var hModuleSnap = NativeMethods.CreateToolhelp32Snapshot(flags, pid); if (hModuleSnap == INVALID_HANDLE_VALUE) { return; } var modEntry = new NativeMethods.MODULEENTRY32() { dwSize = (uint)Marshal.SizeOf(typeof(NativeMethods.MODULEENTRY32)), th32ModuleID = 0 }; if (!NativeMethods.Module32First(hModuleSnap, ref modEntry)) { NativeMethods.CloseHandle(hModuleSnap); return; } do { try { var modPath = modEntry.szExePath; var modInfo = FileVersionInfo.GetVersionInfo(modPath); var modSize = new FileInfo(modPath).Length; var lvi = new ListViewItem(modEntry.szModule) { Tag = modInfo.FileName, ToolTipText = modInfo.FileName + "\n" + modInfo.LegalCopyright + "\n" + modInfo.FileDescription + "\n" + modInfo.ProductVersion }; lvi.SubItems.Add("0x" + modEntry.modBaseAddr.ToString("X4")); lvi.SubItems.Add(FormatByteSize(modSize)); LV_Module.Items.Add(lvi); } catch { break; } }while (NativeMethods.Module32Next(hModuleSnap, ref modEntry)); // Close the object NativeMethods.CloseHandle(hModuleSnap); /* Sort the items and remove the duplicate module name. The ** duplication happens because SnapshotFlags searches for both 32-bit ** and 64-bit modules. Therefore, it adds the main module from both ** TH32CS_SNAPMODULE and TH32CS_SNAPMODULE32. */ LV_Module.Items[0].BackColor = SystemColors.GradientActiveCaption; LV_Module.Sorting = SortOrder.Ascending; for (var i = 0; i < LV_Module.Items.Count - 1; i++) { if (LV_Module.Items[i].Tag.Equals(LV_Module.Items[i + 1].Tag)) { LV_Module.Items[i].BackColor = SystemColors.GradientActiveCaption; LV_Module.Items[i + 1].Remove(); i--; } moduleCount = i; } SetModuleCount(); }