summaryrefslogtreecommitdiffstats
path: root/tools/win
diff options
context:
space:
mode:
authorzturner@chromium.org <zturner@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-21 22:33:51 +0000
committerzturner@chromium.org <zturner@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-21 22:33:51 +0000
commit7041dce98ee6a0d4838a059619c1dac233aab247 (patch)
treed382097693a8d92b586fd4f48ef58c014bb0e485 /tools/win
parenteedf4d86fd753baec4595f1fa7a3b84f61e90870 (diff)
downloadchromium_src-7041dce98ee6a0d4838a059619c1dac233aab247.zip
chromium_src-7041dce98ee6a0d4838a059619c1dac233aab247.tar.gz
chromium_src-7041dce98ee6a0d4838a059619c1dac233aab247.tar.bz2
Various fixes and UI improvements.
* Added executable icon to list view rows. * Use the actual module executable name instead of argv[0] (fixes issue when running not through the shortcut) * Fixes some button anchoring behavior. * Moved the command to the Debug menu instead of Tools menu. BUG=305760 Review URL: https://codereview.chromium.org/27183010 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@229941 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'tools/win')
-rw-r--r--tools/win/ChromeDebug/ChromeDebug/AttachDialog.Designer.cs282
-rw-r--r--tools/win/ChromeDebug/ChromeDebug/AttachDialog.cs21
-rw-r--r--tools/win/ChromeDebug/ChromeDebug/ChromeDebug.vsct6
-rw-r--r--tools/win/ChromeDebug/ChromeDebug/ProcessDetail.cs76
-rw-r--r--tools/win/ChromeDebug/LowLevel/NativeMethods.cs7
-rw-r--r--tools/win/ChromeDebug/LowLevel/Types.cs42
6 files changed, 269 insertions, 165 deletions
diff --git a/tools/win/ChromeDebug/ChromeDebug/AttachDialog.Designer.cs b/tools/win/ChromeDebug/ChromeDebug/AttachDialog.Designer.cs
index 392a7142..3465e3e 100644
--- a/tools/win/ChromeDebug/ChromeDebug/AttachDialog.Designer.cs
+++ b/tools/win/ChromeDebug/ChromeDebug/AttachDialog.Designer.cs
@@ -32,159 +32,154 @@ namespace ChromeDebug
/// </summary>
private void InitializeComponent()
{
- this.listViewProcesses = new System.Windows.Forms.ListView();
- this.columnHeaderDummy = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
- this.columnHeaderProcess = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
- this.columnHeaderPid = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
- this.columnHeaderTitle = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
- this.columnHeaderType = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
- this.columnHeaderSession = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
- this.columnHeaderCmdLine = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
- this.buttonAttach = new System.Windows.Forms.Button();
- this.buttonCancel = new System.Windows.Forms.Button();
- this.groupBox1 = new System.Windows.Forms.GroupBox();
- this.buttonRefresh = new System.Windows.Forms.Button();
- this.checkBoxOnlyChrome = new System.Windows.Forms.CheckBox();
- this.groupBox1.SuspendLayout();
- this.SuspendLayout();
- //
- // listViewProcesses
- //
- this.listViewProcesses.AllowColumnReorder = true;
- this.listViewProcesses.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ this.listViewProcesses = new System.Windows.Forms.ListView();
+ this.columnHeaderProcess = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
+ this.columnHeaderPid = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
+ this.columnHeaderTitle = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
+ this.columnHeaderType = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
+ this.columnHeaderSession = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
+ this.columnHeaderCmdLine = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
+ this.buttonAttach = new System.Windows.Forms.Button();
+ this.buttonCancel = new System.Windows.Forms.Button();
+ this.groupBox1 = new System.Windows.Forms.GroupBox();
+ this.buttonRefresh = new System.Windows.Forms.Button();
+ this.checkBoxOnlyChrome = new System.Windows.Forms.CheckBox();
+ this.groupBox1.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // listViewProcesses
+ //
+ this.listViewProcesses.AllowColumnReorder = true;
+ this.listViewProcesses.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
- this.listViewProcesses.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
- this.columnHeaderDummy,
+ this.listViewProcesses.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.columnHeaderProcess,
this.columnHeaderPid,
this.columnHeaderTitle,
this.columnHeaderType,
this.columnHeaderSession,
this.columnHeaderCmdLine});
- this.listViewProcesses.FullRowSelect = true;
- this.listViewProcesses.Location = new System.Drawing.Point(14, 27);
- this.listViewProcesses.Name = "listViewProcesses";
- this.listViewProcesses.Size = new System.Drawing.Size(884, 462);
- this.listViewProcesses.TabIndex = 0;
- this.listViewProcesses.UseCompatibleStateImageBehavior = false;
- this.listViewProcesses.View = System.Windows.Forms.View.Details;
- //
- // columnHeaderDummy
- //
- this.columnHeaderDummy.Width = 0;
- //
- // columnHeaderProcess
- //
- this.columnHeaderProcess.Text = "Executable";
- this.columnHeaderProcess.Width = 65;
- //
- // columnHeaderPid
- //
- this.columnHeaderPid.Text = "PID";
- this.columnHeaderPid.Width = 30;
- //
- // columnHeaderTitle
- //
- this.columnHeaderTitle.Text = "Title";
- this.columnHeaderTitle.Width = 32;
- //
- // columnHeaderType
- //
- this.columnHeaderType.Text = "Type";
- this.columnHeaderType.Width = 36;
- //
- // columnHeaderSession
- //
- this.columnHeaderSession.Text = "Session";
- this.columnHeaderSession.Width = 49;
- //
- // columnHeaderCmdLine
- //
- this.columnHeaderCmdLine.Text = "Command Line";
- this.columnHeaderCmdLine.Width = 668;
- //
- // buttonAttach
- //
- this.buttonAttach.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
- this.buttonAttach.DialogResult = System.Windows.Forms.DialogResult.OK;
- this.buttonAttach.Location = new System.Drawing.Point(684, 603);
- this.buttonAttach.Name = "buttonAttach";
- this.buttonAttach.Size = new System.Drawing.Size(118, 41);
- this.buttonAttach.TabIndex = 2;
- this.buttonAttach.Text = "Attach";
- this.buttonAttach.UseVisualStyleBackColor = true;
- this.buttonAttach.Click += new System.EventHandler(this.buttonAttach_Click);
- //
- // buttonCancel
- //
- this.buttonCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
- this.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
- this.buttonCancel.Location = new System.Drawing.Point(808, 603);
- this.buttonCancel.Name = "buttonCancel";
- this.buttonCancel.Size = new System.Drawing.Size(118, 41);
- this.buttonCancel.TabIndex = 3;
- this.buttonCancel.Text = "Cancel";
- this.buttonCancel.UseVisualStyleBackColor = true;
- //
- // groupBox1
- //
- this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ this.listViewProcesses.FullRowSelect = true;
+ this.listViewProcesses.Location = new System.Drawing.Point(14, 27);
+ this.listViewProcesses.Name = "listViewProcesses";
+ this.listViewProcesses.Size = new System.Drawing.Size(884, 462);
+ this.listViewProcesses.TabIndex = 0;
+ this.listViewProcesses.UseCompatibleStateImageBehavior = false;
+ this.listViewProcesses.View = System.Windows.Forms.View.Details;
+ //
+ // columnHeaderProcess
+ //
+ this.columnHeaderProcess.Text = "Executable";
+ this.columnHeaderProcess.Width = 65;
+ //
+ // columnHeaderPid
+ //
+ this.columnHeaderPid.Text = "PID";
+ this.columnHeaderPid.Width = 30;
+ //
+ // columnHeaderTitle
+ //
+ this.columnHeaderTitle.Text = "Title";
+ this.columnHeaderTitle.Width = 32;
+ //
+ // columnHeaderType
+ //
+ this.columnHeaderType.Text = "Type";
+ this.columnHeaderType.Width = 36;
+ //
+ // columnHeaderSession
+ //
+ this.columnHeaderSession.Text = "Session";
+ this.columnHeaderSession.Width = 49;
+ //
+ // columnHeaderCmdLine
+ //
+ this.columnHeaderCmdLine.Text = "Command Line";
+ this.columnHeaderCmdLine.Width = 668;
+ //
+ // buttonAttach
+ //
+ this.buttonAttach.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+ this.buttonAttach.DialogResult = System.Windows.Forms.DialogResult.OK;
+ this.buttonAttach.Location = new System.Drawing.Point(684, 603);
+ this.buttonAttach.Name = "buttonAttach";
+ this.buttonAttach.Size = new System.Drawing.Size(118, 41);
+ this.buttonAttach.TabIndex = 2;
+ this.buttonAttach.Text = "Attach";
+ this.buttonAttach.UseVisualStyleBackColor = true;
+ this.buttonAttach.Click += new System.EventHandler(this.buttonAttach_Click);
+ //
+ // buttonCancel
+ //
+ this.buttonCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+ this.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+ this.buttonCancel.Location = new System.Drawing.Point(808, 603);
+ this.buttonCancel.Name = "buttonCancel";
+ this.buttonCancel.Size = new System.Drawing.Size(118, 41);
+ this.buttonCancel.TabIndex = 3;
+ this.buttonCancel.Text = "Cancel";
+ this.buttonCancel.UseVisualStyleBackColor = true;
+ //
+ // groupBox1
+ //
+ this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
- this.groupBox1.Controls.Add(this.listViewProcesses);
- this.groupBox1.Location = new System.Drawing.Point(12, 27);
- this.groupBox1.Name = "groupBox1";
- this.groupBox1.Size = new System.Drawing.Size(914, 511);
- this.groupBox1.TabIndex = 5;
- this.groupBox1.TabStop = false;
- this.groupBox1.Text = "Available Processes";
- //
- // buttonRefresh
- //
- this.buttonRefresh.Location = new System.Drawing.Point(808, 552);
- this.buttonRefresh.Name = "buttonRefresh";
- this.buttonRefresh.Size = new System.Drawing.Size(117, 33);
- this.buttonRefresh.TabIndex = 6;
- this.buttonRefresh.Text = "Refresh";
- this.buttonRefresh.UseVisualStyleBackColor = true;
- this.buttonRefresh.Click += new System.EventHandler(this.buttonRefresh_Click);
- //
- // checkBoxOnlyChrome
- //
- this.checkBoxOnlyChrome.AutoSize = true;
- this.checkBoxOnlyChrome.Checked = true;
- this.checkBoxOnlyChrome.CheckState = System.Windows.Forms.CheckState.Checked;
- this.checkBoxOnlyChrome.Location = new System.Drawing.Point(12, 561);
- this.checkBoxOnlyChrome.Name = "checkBoxOnlyChrome";
- this.checkBoxOnlyChrome.Size = new System.Drawing.Size(165, 17);
- this.checkBoxOnlyChrome.TabIndex = 7;
- this.checkBoxOnlyChrome.Text = "Only show Chrome processes";
- this.checkBoxOnlyChrome.UseVisualStyleBackColor = true;
- this.checkBoxOnlyChrome.CheckedChanged += new System.EventHandler(this.checkBoxOnlyChrome_CheckedChanged);
- //
- // AttachDialog
- //
- this.AcceptButton = this.buttonAttach;
- this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
- this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
- this.CancelButton = this.buttonCancel;
- this.ClientSize = new System.Drawing.Size(940, 656);
- this.ControlBox = false;
- this.Controls.Add(this.checkBoxOnlyChrome);
- this.Controls.Add(this.buttonRefresh);
- this.Controls.Add(this.groupBox1);
- this.Controls.Add(this.buttonCancel);
- this.Controls.Add(this.buttonAttach);
- this.MaximizeBox = false;
- this.MinimizeBox = false;
- this.Name = "AttachDialog";
- this.ShowInTaskbar = false;
- this.Text = "Attach to Chrome";
- this.Load += new System.EventHandler(this.AttachDialog_Load);
- this.groupBox1.ResumeLayout(false);
- this.ResumeLayout(false);
- this.PerformLayout();
+ this.groupBox1.Controls.Add(this.listViewProcesses);
+ this.groupBox1.Location = new System.Drawing.Point(12, 27);
+ this.groupBox1.Name = "groupBox1";
+ this.groupBox1.Size = new System.Drawing.Size(914, 511);
+ this.groupBox1.TabIndex = 5;
+ this.groupBox1.TabStop = false;
+ this.groupBox1.Text = "Available Processes";
+ //
+ // buttonRefresh
+ //
+ this.buttonRefresh.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+ this.buttonRefresh.Location = new System.Drawing.Point(808, 552);
+ this.buttonRefresh.Name = "buttonRefresh";
+ this.buttonRefresh.Size = new System.Drawing.Size(117, 33);
+ this.buttonRefresh.TabIndex = 6;
+ this.buttonRefresh.Text = "Refresh";
+ this.buttonRefresh.UseVisualStyleBackColor = true;
+ this.buttonRefresh.Click += new System.EventHandler(this.buttonRefresh_Click);
+ //
+ // checkBoxOnlyChrome
+ //
+ this.checkBoxOnlyChrome.AutoSize = true;
+ this.checkBoxOnlyChrome.Checked = true;
+ this.checkBoxOnlyChrome.CheckState = System.Windows.Forms.CheckState.Checked;
+ this.checkBoxOnlyChrome.Location = new System.Drawing.Point(12, 561);
+ this.checkBoxOnlyChrome.Name = "checkBoxOnlyChrome";
+ this.checkBoxOnlyChrome.Size = new System.Drawing.Size(165, 17);
+ this.checkBoxOnlyChrome.TabIndex = 7;
+ this.checkBoxOnlyChrome.Text = "Only show Chrome processes";
+ this.checkBoxOnlyChrome.UseVisualStyleBackColor = true;
+ this.checkBoxOnlyChrome.CheckedChanged += new System.EventHandler(this.checkBoxOnlyChrome_CheckedChanged);
+ //
+ // AttachDialog
+ //
+ this.AcceptButton = this.buttonAttach;
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.CancelButton = this.buttonCancel;
+ this.ClientSize = new System.Drawing.Size(940, 656);
+ this.ControlBox = false;
+ this.Controls.Add(this.checkBoxOnlyChrome);
+ this.Controls.Add(this.buttonRefresh);
+ this.Controls.Add(this.groupBox1);
+ this.Controls.Add(this.buttonCancel);
+ this.Controls.Add(this.buttonAttach);
+ this.MaximizeBox = false;
+ this.MinimizeBox = false;
+ this.Name = "AttachDialog";
+ this.ShowInTaskbar = false;
+ this.Text = "Attach to Chrome";
+ this.Load += new System.EventHandler(this.AttachDialog_Load);
+ this.groupBox1.ResumeLayout(false);
+ this.ResumeLayout(false);
+ this.PerformLayout();
}
@@ -197,7 +192,6 @@ namespace ChromeDebug
private System.Windows.Forms.ColumnHeader columnHeaderPid;
private System.Windows.Forms.ColumnHeader columnHeaderTitle;
private System.Windows.Forms.ColumnHeader columnHeaderCmdLine;
- private System.Windows.Forms.ColumnHeader columnHeaderDummy;
private System.Windows.Forms.ColumnHeader columnHeaderType;
private System.Windows.Forms.ColumnHeader columnHeaderSession;
private System.Windows.Forms.GroupBox groupBox1;
diff --git a/tools/win/ChromeDebug/ChromeDebug/AttachDialog.cs b/tools/win/ChromeDebug/ChromeDebug/AttachDialog.cs
index a6505d3..2c38983 100644
--- a/tools/win/ChromeDebug/ChromeDebug/AttachDialog.cs
+++ b/tools/win/ChromeDebug/ChromeDebug/AttachDialog.cs
@@ -127,8 +127,10 @@ namespace ChromeDebug {
item.Title = p.MainWindowTitle;
item.Exe = p.ProcessName;
if (item.CmdLineArgs != null)
- item.Category = DetermineProcessCategory(item.CmdLineArgs);
+ item.Category = DetermineProcessCategory(item.Detail.Win32ProcessImagePath,
+ item.CmdLineArgs);
+ Icon icon = item.Detail.SmallIcon;
List<ProcessViewItem> items = loadedProcessTable[item.Category];
item.Group = processGroups[item.Category];
items.Add(item);
@@ -147,11 +149,11 @@ namespace ChromeDebug {
// Using a heuristic based on the command line, tries to determine what type of process this
// is.
- private ProcessCategory DetermineProcessCategory(string[] cmdline) {
+ private ProcessCategory DetermineProcessCategory(string imagePath, string[] cmdline) {
if (cmdline == null || cmdline.Length == 0)
return ProcessCategory.Other;
- string file = Path.GetFileName(cmdline[0]);
+ string file = Path.GetFileName(imagePath);
if (file.Equals("delegate_execute.exe", StringComparison.CurrentCultureIgnoreCase))
return ProcessCategory.DelegateExecute;
else if (file.Equals("chrome.exe", StringComparison.CurrentCultureIgnoreCase)) {
@@ -173,13 +175,19 @@ namespace ChromeDebug {
private void InsertCategoryItems(ProcessCategory category) {
foreach (ProcessViewItem item in loadedProcessTable[category]) {
- item.SubItems.Add(item.Exe);
+ item.Text = item.Exe;
item.SubItems.Add(item.ProcessId.ToString());
item.SubItems.Add(item.Title);
item.SubItems.Add(item.MachineType.ToString());
item.SubItems.Add(item.SessionId.ToString());
item.SubItems.Add(item.DisplayCmdLine);
listViewProcesses.Items.Add(item);
+
+ Icon icon = item.Detail.SmallIcon;
+ if (icon != null) {
+ item.ImageList.Images.Add(icon);
+ item.ImageIndex = item.ImageList.Images.Count - 1;
+ }
}
}
@@ -196,9 +204,8 @@ namespace ChromeDebug {
listViewProcesses.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent);
// Finally, iterate over each column, and resize those columns that just got smaller.
- listViewProcesses.Columns[0].Width = 0;
int total = 0;
- for (int i = 1; i < listViewProcesses.Columns.Count; ++i) {
+ for (int i = 0; i < listViewProcesses.Columns.Count; ++i) {
// Resize to the largest of the two, but don't let it go over a pre-defined maximum.
int max = Math.Max(listViewProcesses.Columns[i].Width, widths[i]);
int capped = Math.Min(max, 300);
@@ -216,6 +223,8 @@ namespace ChromeDebug {
private void RepopulateListView() {
listViewProcesses.Items.Clear();
+ listViewProcesses.SmallImageList = new ImageList();
+ listViewProcesses.SmallImageList.ImageSize = new Size(16, 16);
ReloadNativeProcessInfo();
diff --git a/tools/win/ChromeDebug/ChromeDebug/ChromeDebug.vsct b/tools/win/ChromeDebug/ChromeDebug/ChromeDebug.vsct
index ca02527..bfc9246 100644
--- a/tools/win/ChromeDebug/ChromeDebug/ChromeDebug.vsct
+++ b/tools/win/ChromeDebug/ChromeDebug/ChromeDebug.vsct
@@ -21,6 +21,10 @@
<!--This header contains the command ids for the menus provided by the shell. -->
<Extern href="vsshlids.h"/>
+ <!--These headers contain the menu guids for attaching commands to the debug menu. -->
+ <Extern href="VSDbgCmd.h"/>
+ <Extern href="VSDebugGuids.h"/>
+
@@ -44,7 +48,7 @@
<Groups>
<Group guid="guidChromeDebugCmdSet" id="MyMenuGroup" priority="0x0600">
- <Parent guid="guidSHLMainMenu" id="IDM_VS_MENU_TOOLS"/>
+ <Parent guid="guidVSDebugGroup" id="IDM_DEBUG_MENU"/>
</Group>
diff --git a/tools/win/ChromeDebug/ChromeDebug/ProcessDetail.cs b/tools/win/ChromeDebug/ChromeDebug/ProcessDetail.cs
index fbbb358..973ea0c 100644
--- a/tools/win/ChromeDebug/ChromeDebug/ProcessDetail.cs
+++ b/tools/win/ChromeDebug/ChromeDebug/ProcessDetail.cs
@@ -12,6 +12,8 @@ using System.Text;
using System.Threading.Tasks;
using ChromeDebug.LowLevel;
+using System.Runtime.InteropServices;
+using System.Drawing;
namespace ChromeDebug {
internal class ProcessDetail : IDisposable {
@@ -44,6 +46,43 @@ namespace ChromeDebug {
}
}
+ public string NativeProcessImagePath {
+ get {
+ if (nativeProcessImagePath == null) {
+ nativeProcessImagePath = QueryProcessImageName(
+ LowLevelTypes.ProcessQueryImageNameMode.NATIVE_SYSTEM_FORMAT);
+ }
+ return nativeProcessImagePath;
+ }
+ }
+
+ public string Win32ProcessImagePath {
+ get {
+ if (win32ProcessImagePath == null) {
+ win32ProcessImagePath = QueryProcessImageName(
+ LowLevelTypes.ProcessQueryImageNameMode.WIN32_FORMAT);
+ }
+ return win32ProcessImagePath;
+ }
+ }
+
+ public Icon SmallIcon {
+ get {
+ LowLevel.LowLevelTypes.SHFILEINFO info = new LowLevelTypes.SHFILEINFO(true);
+ LowLevel.LowLevelTypes.SHGFI flags = LowLevel.LowLevelTypes.SHGFI.Icon
+ | LowLevelTypes.SHGFI.SmallIcon
+ | LowLevelTypes.SHGFI.OpenIcon
+ | LowLevelTypes.SHGFI.UseFileAttributes;
+ int cbFileInfo = Marshal.SizeOf(info);
+ LowLevel.NativeMethods.SHGetFileInfo(Win32ProcessImagePath,
+ 256,
+ ref info,
+ (uint)cbFileInfo,
+ (uint)flags);
+ return Icon.FromHandle(info.hIcon);
+ }
+ }
+
// Returns the command line that this process was launched with. Uses lazy evaluation and
// caches the result. Reads the command line from the PEB of the running process.
public string CommandLine {
@@ -92,6 +131,19 @@ namespace ChromeDebug {
}
}
+ private string QueryProcessImageName(LowLevelTypes.ProcessQueryImageNameMode mode) {
+ StringBuilder moduleBuffer = new StringBuilder(1024);
+ int size = moduleBuffer.Capacity;
+ NativeMethods.QueryFullProcessImageName(
+ processHandle,
+ mode,
+ moduleBuffer,
+ ref size);
+ if (mode == LowLevelTypes.ProcessQueryImageNameMode.NATIVE_SYSTEM_FORMAT)
+ moduleBuffer.Insert(0, "\\\\?\\GLOBALROOT");
+ return moduleBuffer.ToString();
+ }
+
// Loads the top-level structure of the process's information block and caches it.
private void CacheProcessInformation() {
System.Diagnostics.Debug.Assert(CanReadPeb);
@@ -151,29 +203,19 @@ namespace ChromeDebug {
private void CacheMachineType() {
System.Diagnostics.Debug.Assert(CanQueryProcessInformation);
- StringBuilder moduleBuffer = new StringBuilder(1024);
- int size = moduleBuffer.Capacity;
-
// If our extension is running in a 32-bit process (which it is), then attempts to access
// files in C:\windows\system (and a few other files) will redirect to C:\Windows\SysWOW64
// and we will mistakenly think that the image file is a 32-bit image. The way around this
// is to use a native system format path, of the form:
// \\?\GLOBALROOT\Device\HarddiskVolume0\Windows\System\foo.dat
- // By using the NATIVE_SYSTEM_FORMAT flag to QueryFullProcessImageName, we can get the path
- // in this format.
- NativeMethods.QueryFullProcessImageName(
- processHandle,
- LowLevelTypes.ProcessQueryImageNameMode.NATIVE_SYSTEM_FORMAT,
- moduleBuffer,
- ref size);
- moduleBuffer.Insert(0, "\\\\?\\GLOBALROOT");
- string module = moduleBuffer.ToString();
+ // NativeProcessImagePath gives us the full process image path in the desired format.
+ string path = NativeProcessImagePath;
// Open the PE File as a binary file, and parse just enough information to determine the
// machine type.
//http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx
using (SafeFileHandle safeHandle = NativeMethods.CreateFile(
- module,
+ path,
LowLevelTypes.FileAccessFlags.GENERIC_READ,
LowLevelTypes.FileShareFlags.SHARE_READ,
IntPtr.Zero,
@@ -214,7 +256,9 @@ namespace ChromeDebug {
// open with.
private int processId;
private IntPtr processHandle;
- LowLevelTypes.ProcessAccessFlags processHandleFlags;
+ private LowLevelTypes.ProcessAccessFlags processHandleFlags;
+ private string nativeProcessImagePath;
+ private string win32ProcessImagePath;
// The machine type is read by parsing the PE image file of the running process, so we cache
// its value since the operation expensive.
@@ -229,6 +273,10 @@ namespace ChromeDebug {
private Nullable<LowLevelTypes.RTL_USER_PROCESS_PARAMETERS> cachedProcessParams;
private string cachedCommandLine;
+ ~ProcessDetail() {
+ Dispose();
+ }
+
public void Dispose() {
if (processHandle != IntPtr.Zero)
NativeMethods.CloseHandle(processHandle);
diff --git a/tools/win/ChromeDebug/LowLevel/NativeMethods.cs b/tools/win/ChromeDebug/LowLevel/NativeMethods.cs
index 4fb46fd..170cd91 100644
--- a/tools/win/ChromeDebug/LowLevel/NativeMethods.cs
+++ b/tools/win/ChromeDebug/LowLevel/NativeMethods.cs
@@ -61,5 +61,12 @@ namespace ChromeDebug.LowLevel {
LowLevelTypes.FileCreationDisposition dwDisp,
LowLevelTypes.FileFlagsAndAttributes dwFlags,
IntPtr hTemplateFile);
+
+ [DllImport("shell32.dll", CharSet = CharSet.Unicode)]
+ public static extern IntPtr SHGetFileInfo(string pszPath,
+ uint dwFileAttributes,
+ ref LowLevelTypes.SHFILEINFO psfi,
+ uint cbFileInfo,
+ uint uFlags);
}
}
diff --git a/tools/win/ChromeDebug/LowLevel/Types.cs b/tools/win/ChromeDebug/LowLevel/Types.cs
index 17fc19b..483acf7 100644
--- a/tools/win/ChromeDebug/LowLevel/Types.cs
+++ b/tools/win/ChromeDebug/LowLevel/Types.cs
@@ -102,6 +102,28 @@ namespace ChromeDebug.LowLevel {
public enum PROCESSINFOCLASS : int {
PROCESS_BASIC_INFORMATION = 0
};
+
+ [Flags]
+ public enum SHGFI : uint {
+ Icon = 0x000000100,
+ DisplayName = 0x000000200,
+ TypeName = 0x000000400,
+ Attributes = 0x000000800,
+ IconLocation = 0x000001000,
+ ExeType = 0x000002000,
+ SysIconIndex = 0x000004000,
+ LinkOverlay = 0x000008000,
+ Selected = 0x000010000,
+ Attr_Specified = 0x000020000,
+ LargeIcon = 0x000000000,
+ SmallIcon = 0x000000001,
+ OpenIcon = 0x000000002,
+ ShellIconSize = 0x000000004,
+ PIDL = 0x000000008,
+ UseFileAttributes = 0x000000010,
+ AddOverlays = 0x000000020,
+ OverlayIndex = 0x000000040,
+ }
#endregion
#region Structures
@@ -172,6 +194,26 @@ namespace ChromeDebug.LowLevel {
public IntPtr PebBaseAddress { get { return pebBaseAddress; } }
public UIntPtr UniqueProcessId { get { return uniqueProcessId; } }
}
+
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
+ public struct SHFILEINFO {
+ // C# doesn't support overriding the default constructor of value types, so we need to use
+ // a dummy constructor.
+ public SHFILEINFO(bool dummy) {
+ hIcon = IntPtr.Zero;
+ iIcon = 0;
+ dwAttributes = 0;
+ szDisplayName = "";
+ szTypeName = "";
+ }
+ public IntPtr hIcon;
+ public int iIcon;
+ public uint dwAttributes;
+ [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
+ public string szDisplayName;
+ [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
+ public string szTypeName;
+ };
#endregion
}
}