Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(11)

Side by Side Diff: tools/win/ChromeDebug/ChromeDebug/AttachDialog.cs

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

Powered by Google App Engine
This is Rietveld 408576698