| Index: trunk/src/tools/win/ChromeDebug/ChromeDebug/AttachDialog.cs
|
| ===================================================================
|
| --- trunk/src/tools/win/ChromeDebug/ChromeDebug/AttachDialog.cs (revision 223795)
|
| +++ trunk/src/tools/win/ChromeDebug/ChromeDebug/AttachDialog.cs (working copy)
|
| @@ -1,250 +0,0 @@
|
| -using System;
|
| -using System.Collections.Generic;
|
| -using System.ComponentModel;
|
| -using System.Data;
|
| -using System.Diagnostics;
|
| -using System.Drawing;
|
| -using System.IO;
|
| -using System.Linq;
|
| -using System.Management;
|
| -using System.Text;
|
| -using System.Threading.Tasks;
|
| -using System.Windows.Forms;
|
| -
|
| -using ChromeDebug.LowLevel;
|
| -
|
| -namespace ChromeDebug {
|
| - // The form that is displayed to allow the user to select processes to attach to. Note that we
|
| - // cannot interact with the DTE object from here (I assume this is because the dialog is running
|
| - // on a different thread, although I don't fully understand), so any access to the DTE object
|
| - // will have to be done through events that get posted back to the main package thread.
|
| - public partial class AttachDialog : Form {
|
| - private class ProcessViewItem : ListViewItem {
|
| - public ProcessViewItem() {
|
| - Category = ProcessCategory.Other;
|
| - MachineType = LowLevelTypes.MachineType.UNKNOWN;
|
| - }
|
| -
|
| - public string Exe;
|
| - public int ProcessId;
|
| - public int SessionId;
|
| - public string Title;
|
| - public string DisplayCmdLine;
|
| - public string[] CmdLineArgs;
|
| - public ProcessCategory Category;
|
| - public LowLevelTypes.MachineType MachineType;
|
| -
|
| - public ProcessDetail Detail;
|
| - }
|
| -
|
| - private Dictionary<ProcessCategory, List<ProcessViewItem>> loadedProcessTable = null;
|
| - private Dictionary<ProcessCategory, ListViewGroup> processGroups = null;
|
| - private List<int> selectedProcesses = null;
|
| -
|
| - public AttachDialog() {
|
| - InitializeComponent();
|
| -
|
| - loadedProcessTable = new Dictionary<ProcessCategory, List<ProcessViewItem>>();
|
| - processGroups = new Dictionary<ProcessCategory, ListViewGroup>();
|
| - selectedProcesses = new List<int>();
|
| -
|
| - // Create and initialize the groups and process lists only once. On a reset
|
| - // we don't clear the groups manually, clearing the list view should clear the
|
| - // groups. And we don't clear the entire processes_ dictionary, only the
|
| - // individual buckets inside the dictionary.
|
| - foreach (object value in Enum.GetValues(typeof(ProcessCategory))) {
|
| - ProcessCategory category = (ProcessCategory)value;
|
| -
|
| - ListViewGroup group = new ListViewGroup(category.ToGroupTitle());
|
| - processGroups[category] = group;
|
| - listViewProcesses.Groups.Add(group);
|
| -
|
| - loadedProcessTable[category] = new List<ProcessViewItem>();
|
| - }
|
| - }
|
| -
|
| - // Provides an iterator that evaluates to the process ids of the entries that are selected
|
| - // in the list view.
|
| - public IEnumerable<int> SelectedItems {
|
| - get {
|
| - foreach (ProcessViewItem item in listViewProcesses.SelectedItems)
|
| - yield return item.ProcessId;
|
| - }
|
| - }
|
| -
|
| - private void AttachDialog_Load(object sender, EventArgs e) {
|
| - RepopulateListView();
|
| - }
|
| -
|
| - // Remove command line arguments that we aren't interested in displaying as part of the command
|
| - // line of the process.
|
| - private string[] FilterCommandLine(string[] args) {
|
| - Func<string, int, bool> AllowArgument = delegate(string arg, int index) {
|
| - if (index == 0)
|
| - return false;
|
| - return !arg.StartsWith("--force-fieldtrials", StringComparison.CurrentCultureIgnoreCase);
|
| - };
|
| -
|
| - // The force-fieldtrials command line option makes the command line view useless, so remove
|
| - // it. Also remove args[0] since that is the process name.
|
| - args = args.Where(AllowArgument).ToArray();
|
| - return args;
|
| - }
|
| -
|
| - private void ReloadNativeProcessInfo() {
|
| - foreach (List<ProcessViewItem> list in loadedProcessTable.Values) {
|
| - list.Clear();
|
| - }
|
| -
|
| - Process[] processes = Process.GetProcesses();
|
| - foreach (Process p in processes) {
|
| - ProcessViewItem item = new ProcessViewItem();
|
| - try {
|
| - item.Detail = new ProcessDetail(p.Id);
|
| - if (item.Detail.CanReadPeb && item.Detail.CommandLine != null) {
|
| - item.CmdLineArgs = Utility.SplitArgs(item.Detail.CommandLine);
|
| - item.DisplayCmdLine = GetFilteredCommandLineString(item.CmdLineArgs);
|
| - }
|
| - item.MachineType = item.Detail.MachineType;
|
| - }
|
| - catch (Exception) {
|
| - // Generally speaking, an exception here means the process is privileged and we cannot
|
| - // get any information about the process. For those processes, we will just display the
|
| - // information that the Framework gave us in the Process structure.
|
| - }
|
| -
|
| - // If we don't have the machine type, its privilege level is high enough that we won't be
|
| - // able to attach a debugger to it anyway, so skip it.
|
| - if (item.MachineType == LowLevelTypes.MachineType.UNKNOWN)
|
| - continue;
|
| -
|
| - item.ProcessId = p.Id;
|
| - item.SessionId = p.SessionId;
|
| - item.Title = p.MainWindowTitle;
|
| - item.Exe = p.ProcessName;
|
| - if (item.CmdLineArgs != null)
|
| - item.Category = DetermineProcessCategory(item.CmdLineArgs);
|
| -
|
| - List<ProcessViewItem> items = loadedProcessTable[item.Category];
|
| - item.Group = processGroups[item.Category];
|
| - items.Add(item);
|
| - }
|
| - }
|
| -
|
| - // Filter the command line arguments to remove extraneous arguments that we don't wish to
|
| - // display.
|
| - private string GetFilteredCommandLineString(string[] args) {
|
| - if (args == null || args.Length == 0)
|
| - return string.Empty;
|
| -
|
| - args = FilterCommandLine(args);
|
| - return string.Join(" ", args, 0, args.Length);
|
| - }
|
| -
|
| - // Using a heuristic based on the command line, tries to determine what type of process this
|
| - // is.
|
| - private ProcessCategory DetermineProcessCategory(string[] cmdline) {
|
| - if (cmdline == null || cmdline.Length == 0)
|
| - return ProcessCategory.Other;
|
| -
|
| - string file = Path.GetFileName(cmdline[0]);
|
| - if (file.Equals("delegate_execute.exe", StringComparison.CurrentCultureIgnoreCase))
|
| - return ProcessCategory.DelegateExecute;
|
| - else if (file.Equals("chrome.exe", StringComparison.CurrentCultureIgnoreCase)) {
|
| - if (cmdline.Contains("--type=renderer"))
|
| - return ProcessCategory.Renderer;
|
| - else if (cmdline.Contains("--type=plugin") || cmdline.Contains("--type=ppapi"))
|
| - return ProcessCategory.Plugin;
|
| - else if (cmdline.Contains("--type=gpu-process"))
|
| - return ProcessCategory.Gpu;
|
| - else if (cmdline.Contains("--type=service"))
|
| - return ProcessCategory.Service;
|
| - else if (cmdline.Any(arg => arg.StartsWith("-ServerName")))
|
| - return ProcessCategory.MetroViewer;
|
| - else
|
| - return ProcessCategory.Browser;
|
| - } else
|
| - return ProcessCategory.Other;
|
| - }
|
| -
|
| - private void InsertCategoryItems(ProcessCategory category) {
|
| - foreach (ProcessViewItem item in loadedProcessTable[category]) {
|
| - item.SubItems.Add(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);
|
| - }
|
| - }
|
| -
|
| - private void AutoResizeColumns() {
|
| - // First adjust to the width of the headers, since it's fast.
|
| - listViewProcesses.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);
|
| -
|
| - // Save the widths so we can use them again later.
|
| - List<int> widths = new List<int>();
|
| - foreach (ColumnHeader header in listViewProcesses.Columns)
|
| - widths.Add(header.Width);
|
| -
|
| - // Now let Windows do the slow adjustment based on the content.
|
| - 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) {
|
| - // 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);
|
| -
|
| - // We do still want to fill up the available space in the list view however, so if we're
|
| - // under then we can fill.
|
| - int globalMinWidth = listViewProcesses.Width - SystemInformation.VerticalScrollBarWidth;
|
| - if (i == listViewProcesses.Columns.Count - 1 && (total + capped) < (globalMinWidth - 4))
|
| - capped = globalMinWidth - total - 4;
|
| -
|
| - total += capped;
|
| - listViewProcesses.Columns[i].Width = capped;
|
| - }
|
| - }
|
| -
|
| - private void RepopulateListView() {
|
| - listViewProcesses.Items.Clear();
|
| -
|
| - ReloadNativeProcessInfo();
|
| -
|
| - InsertCategoryItems(ProcessCategory.Browser);
|
| - InsertCategoryItems(ProcessCategory.Renderer);
|
| - InsertCategoryItems(ProcessCategory.Gpu);
|
| - InsertCategoryItems(ProcessCategory.Plugin);
|
| - InsertCategoryItems(ProcessCategory.MetroViewer);
|
| - InsertCategoryItems(ProcessCategory.Service);
|
| - InsertCategoryItems(ProcessCategory.DelegateExecute);
|
| - if (!checkBoxOnlyChrome.Checked)
|
| - InsertCategoryItems(ProcessCategory.Other);
|
| -
|
| - AutoResizeColumns();
|
| - }
|
| -
|
| - private void buttonRefresh_Click(object sender, EventArgs e) {
|
| - RepopulateListView();
|
| - }
|
| -
|
| - private void buttonAttach_Click(object sender, EventArgs e) {
|
| - System.Diagnostics.Debug.WriteLine("Closing dialog.");
|
| - this.Close();
|
| - }
|
| -
|
| - private void checkBoxOnlyChrome_CheckedChanged(object sender, EventArgs e) {
|
| - if (!checkBoxOnlyChrome.Checked)
|
| - InsertCategoryItems(ProcessCategory.Other);
|
| - else {
|
| - foreach (ProcessViewItem item in loadedProcessTable[ProcessCategory.Other]) {
|
| - listViewProcesses.Items.Remove(item);
|
| - }
|
| - }
|
| - }
|
| - }
|
| -}
|
|
|