1d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// found in the LICENSE file. 4d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 5d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)using System; 6d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)using System.Collections.Generic; 7d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)using System.ComponentModel; 8d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)using System.Data; 9d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)using System.Diagnostics; 10d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)using System.Drawing; 11d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)using System.IO; 12d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)using System.Linq; 13d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)using System.Management; 14d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)using System.Text; 15d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)using System.Threading.Tasks; 16d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)using System.Windows.Forms; 17d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 18d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)using ChromeDebug.LowLevel; 19d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 20d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)namespace ChromeDebug { 21d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // The form that is displayed to allow the user to select processes to attach to. Note that we 22d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // cannot interact with the DTE object from here (I assume this is because the dialog is running 23d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // on a different thread, although I don't fully understand), so any access to the DTE object 24d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // will have to be done through events that get posted back to the main package thread. 25d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public partial class AttachDialog : Form { 26d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private class ProcessViewItem : ListViewItem { 27d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public ProcessViewItem() { 28d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) Category = ProcessCategory.Other; 29d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) MachineType = LowLevelTypes.MachineType.UNKNOWN; 30d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 31d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 32d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public string Exe; 33d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public int ProcessId; 34d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public int SessionId; 35d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public string Title; 36d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public string DisplayCmdLine; 37d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public string[] CmdLineArgs; 38d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public ProcessCategory Category; 39d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public LowLevelTypes.MachineType MachineType; 40d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 41d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public ProcessDetail Detail; 42d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 43d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 44d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private Dictionary<ProcessCategory, List<ProcessViewItem>> loadedProcessTable = null; 45d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private Dictionary<ProcessCategory, ListViewGroup> processGroups = null; 46d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private List<int> selectedProcesses = null; 47d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 48d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public AttachDialog() { 49d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) InitializeComponent(); 50d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 51d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) loadedProcessTable = new Dictionary<ProcessCategory, List<ProcessViewItem>>(); 52d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) processGroups = new Dictionary<ProcessCategory, ListViewGroup>(); 53d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) selectedProcesses = new List<int>(); 54d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 55d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Create and initialize the groups and process lists only once. On a reset 56d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // we don't clear the groups manually, clearing the list view should clear the 57d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // groups. And we don't clear the entire processes_ dictionary, only the 58d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // individual buckets inside the dictionary. 59d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) foreach (object value in Enum.GetValues(typeof(ProcessCategory))) { 60d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ProcessCategory category = (ProcessCategory)value; 61d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 62d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ListViewGroup group = new ListViewGroup(category.ToGroupTitle()); 63d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) processGroups[category] = group; 64d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) listViewProcesses.Groups.Add(group); 65d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 66d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) loadedProcessTable[category] = new List<ProcessViewItem>(); 67d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 68d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 69d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 70d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Provides an iterator that evaluates to the process ids of the entries that are selected 71d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // in the list view. 72d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public IEnumerable<int> SelectedItems { 73d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) get { 74d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) foreach (ProcessViewItem item in listViewProcesses.SelectedItems) 75d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) yield return item.ProcessId; 76d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 77d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 78d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 79d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private void AttachDialog_Load(object sender, EventArgs e) { 80d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) RepopulateListView(); 81d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 82d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 83d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Remove command line arguments that we aren't interested in displaying as part of the command 84d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // line of the process. 85d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private string[] FilterCommandLine(string[] args) { 86d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) Func<string, int, bool> AllowArgument = delegate(string arg, int index) { 87d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (index == 0) 88d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return false; 89d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return !arg.StartsWith("--force-fieldtrials", StringComparison.CurrentCultureIgnoreCase); 90d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) }; 91d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 92d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // The force-fieldtrials command line option makes the command line view useless, so remove 93d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // it. Also remove args[0] since that is the process name. 94d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) args = args.Where(AllowArgument).ToArray(); 95d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return args; 96d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 97d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 98d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private void ReloadNativeProcessInfo() { 99d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) foreach (List<ProcessViewItem> list in loadedProcessTable.Values) { 100d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) list.Clear(); 101d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 102d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 103d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) Process[] processes = Process.GetProcesses(); 104d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) foreach (Process p in processes) { 105d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ProcessViewItem item = new ProcessViewItem(); 106d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) try { 107d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) item.Detail = new ProcessDetail(p.Id); 108d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (item.Detail.CanReadPeb && item.Detail.CommandLine != null) { 109d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) item.CmdLineArgs = Utility.SplitArgs(item.Detail.CommandLine); 110d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) item.DisplayCmdLine = GetFilteredCommandLineString(item.CmdLineArgs); 111d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 112d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) item.MachineType = item.Detail.MachineType; 113d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 114d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) catch (Exception) { 115d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Generally speaking, an exception here means the process is privileged and we cannot 116d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // get any information about the process. For those processes, we will just display the 117d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // information that the Framework gave us in the Process structure. 118d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 119d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 120d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // If we don't have the machine type, its privilege level is high enough that we won't be 121d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // able to attach a debugger to it anyway, so skip it. 122d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (item.MachineType == LowLevelTypes.MachineType.UNKNOWN) 123d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) continue; 124d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 125d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) item.ProcessId = p.Id; 126d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) item.SessionId = p.SessionId; 127d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) item.Title = p.MainWindowTitle; 128d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) item.Exe = p.ProcessName; 129d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (item.CmdLineArgs != null) 1308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) item.Category = DetermineProcessCategory(item.Detail.Win32ProcessImagePath, 1318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) item.CmdLineArgs); 132d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 1338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) Icon icon = item.Detail.SmallIcon; 134d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) List<ProcessViewItem> items = loadedProcessTable[item.Category]; 135d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) item.Group = processGroups[item.Category]; 136d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) items.Add(item); 137d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 138d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 139d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 140d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Filter the command line arguments to remove extraneous arguments that we don't wish to 141d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // display. 142d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private string GetFilteredCommandLineString(string[] args) { 143d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (args == null || args.Length == 0) 144d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return string.Empty; 145d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 146d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) args = FilterCommandLine(args); 147d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return string.Join(" ", args, 0, args.Length); 148d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 149d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 150d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Using a heuristic based on the command line, tries to determine what type of process this 151d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // is. 1528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) private ProcessCategory DetermineProcessCategory(string imagePath, string[] cmdline) { 153d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (cmdline == null || cmdline.Length == 0) 154d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return ProcessCategory.Other; 155d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 1568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) string file = Path.GetFileName(imagePath); 157d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (file.Equals("delegate_execute.exe", StringComparison.CurrentCultureIgnoreCase)) 158d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return ProcessCategory.DelegateExecute; 159d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) else if (file.Equals("chrome.exe", StringComparison.CurrentCultureIgnoreCase)) { 160d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (cmdline.Contains("--type=renderer")) 161d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return ProcessCategory.Renderer; 162d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) else if (cmdline.Contains("--type=plugin") || cmdline.Contains("--type=ppapi")) 163d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return ProcessCategory.Plugin; 164d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) else if (cmdline.Contains("--type=gpu-process")) 165d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return ProcessCategory.Gpu; 166d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) else if (cmdline.Contains("--type=service")) 167d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return ProcessCategory.Service; 168d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) else if (cmdline.Any(arg => arg.StartsWith("-ServerName"))) 169d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return ProcessCategory.MetroViewer; 170d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) else 171d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return ProcessCategory.Browser; 172d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } else 173d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return ProcessCategory.Other; 174d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 175d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 176d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private void InsertCategoryItems(ProcessCategory category) { 177d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) foreach (ProcessViewItem item in loadedProcessTable[category]) { 1788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) item.Text = item.Exe; 179d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) item.SubItems.Add(item.ProcessId.ToString()); 180d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) item.SubItems.Add(item.Title); 181d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) item.SubItems.Add(item.MachineType.ToString()); 182d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) item.SubItems.Add(item.SessionId.ToString()); 183d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) item.SubItems.Add(item.DisplayCmdLine); 184d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) listViewProcesses.Items.Add(item); 1858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) Icon icon = item.Detail.SmallIcon; 1878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (icon != null) { 1888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) item.ImageList.Images.Add(icon); 1898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) item.ImageIndex = item.ImageList.Images.Count - 1; 1908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 191d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 192d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 193d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 194d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private void AutoResizeColumns() { 195d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // First adjust to the width of the headers, since it's fast. 196d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) listViewProcesses.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize); 197d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 198d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Save the widths so we can use them again later. 199d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) List<int> widths = new List<int>(); 200d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) foreach (ColumnHeader header in listViewProcesses.Columns) 201d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) widths.Add(header.Width); 202d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 203d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Now let Windows do the slow adjustment based on the content. 204d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) listViewProcesses.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent); 205d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 206d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Finally, iterate over each column, and resize those columns that just got smaller. 207d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) int total = 0; 2088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) for (int i = 0; i < listViewProcesses.Columns.Count; ++i) { 209d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Resize to the largest of the two, but don't let it go over a pre-defined maximum. 210d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) int max = Math.Max(listViewProcesses.Columns[i].Width, widths[i]); 211d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) int capped = Math.Min(max, 300); 212d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 213d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // We do still want to fill up the available space in the list view however, so if we're 214d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // under then we can fill. 215d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) int globalMinWidth = listViewProcesses.Width - SystemInformation.VerticalScrollBarWidth; 216d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (i == listViewProcesses.Columns.Count - 1 && (total + capped) < (globalMinWidth - 4)) 217d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) capped = globalMinWidth - total - 4; 218d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 219d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) total += capped; 220d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) listViewProcesses.Columns[i].Width = capped; 221d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 222d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 223d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 224d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private void RepopulateListView() { 225d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) listViewProcesses.Items.Clear(); 2268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) listViewProcesses.SmallImageList = new ImageList(); 2278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) listViewProcesses.SmallImageList.ImageSize = new Size(16, 16); 228d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 229d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ReloadNativeProcessInfo(); 230d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 231d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) InsertCategoryItems(ProcessCategory.Browser); 232d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) InsertCategoryItems(ProcessCategory.Renderer); 233d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) InsertCategoryItems(ProcessCategory.Gpu); 234d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) InsertCategoryItems(ProcessCategory.Plugin); 235d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) InsertCategoryItems(ProcessCategory.MetroViewer); 236d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) InsertCategoryItems(ProcessCategory.Service); 237d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) InsertCategoryItems(ProcessCategory.DelegateExecute); 238d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (!checkBoxOnlyChrome.Checked) 239d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) InsertCategoryItems(ProcessCategory.Other); 240d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 241d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) AutoResizeColumns(); 242d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 243d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 244d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private void buttonRefresh_Click(object sender, EventArgs e) { 245d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) RepopulateListView(); 246d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 247d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 248d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private void buttonAttach_Click(object sender, EventArgs e) { 249d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) System.Diagnostics.Debug.WriteLine("Closing dialog."); 250d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) this.Close(); 251d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 252d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 253d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private void checkBoxOnlyChrome_CheckedChanged(object sender, EventArgs e) { 254d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (!checkBoxOnlyChrome.Checked) 255d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) InsertCategoryItems(ProcessCategory.Other); 256d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) else { 257d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) foreach (ProcessViewItem item in loadedProcessTable[ProcessCategory.Other]) { 258d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) listViewProcesses.Items.Remove(item); 259d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 260d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 261d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 262d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 263d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 264