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.Diagnostics;
7d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)using System.Globalization;
8d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)using System.Runtime.InteropServices;
9d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)using System.ComponentModel.Design;
10d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)using Microsoft.Win32;
11d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)using Microsoft.VisualStudio;
12d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)using Microsoft.VisualStudio.Shell.Interop;
13d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)using Microsoft.VisualStudio.OLE.Interop;
14d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)using Microsoft.VisualStudio.Shell;
15d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)using System.Windows.Forms;
16d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
17d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)namespace ChromeDebug {
18d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  /// <summary>
19d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  /// This is the class that implements the package exposed by this assembly.
20d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  ///
21d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  /// The minimum requirement for a class to be considered a valid package for Visual Studio
22d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  /// is to implement the IVsPackage interface and register itself with the shell.
23d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  /// This package uses the helper classes defined inside the Managed Package Framework (MPF)
24d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  /// to do it: it derives from the Package class that provides the implementation of the
25d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  /// IVsPackage interface and uses the registration attributes defined in the framework to
26d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  /// register itself and its components with the shell.
27d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  /// </summary>
28d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // This attribute tells the PkgDef creation utility (CreatePkgDef.exe) that this class is
29d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // a package.
30d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  [PackageRegistration(UseManagedResourcesOnly = true)]
31d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // This attribute is used to register the information needed to show this package
32d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // in the Help/About dialog of Visual Studio.
33d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  [InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)]
34d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // This attribute is needed to let the shell know that this package exposes some menus.
35d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  [ProvideMenuResource("Menus.ctmenu", 1)]
36d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  [Guid(GuidList.guidChromeDebugPkgString)]
37d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  public sealed class ChromeDebugPackage : Package {
38d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    /// <summary>
39d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    /// Default constructor of the package.
40d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    /// Inside this method you can place any initialization code that does not require
41d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    /// any Visual Studio service because at this point the package object is created but
42d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    /// not sited yet inside Visual Studio environment. The place to do all the other
43d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    /// initialization is the Initialize method.
44d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    /// </summary>
45d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    public ChromeDebugPackage() {
46d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "Entering constructor for: {0}",
47d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          this.ToString()));
48d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    }
49d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
50d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
51d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
52d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    /////////////////////////////////////////////////////////////////////////////
53d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // Overridden Package Implementation
54d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    #region Package Members
55d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
56d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    /// <summary>
57d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    /// Initialization of the package; this method is called right after the package is sited, so this is the place
58d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    /// where you can put all the initialization code that rely on services provided by VisualStudio.
59d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    /// </summary>
60d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    protected override void Initialize() {
61d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "Entering Initialize() of: {0}", this.ToString()));
62d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      base.Initialize();
63d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
64d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      // Add our command handlers for menu (commands must exist in the .vsct file)
65d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      OleMenuCommandService mcs = GetService(typeof(IMenuCommandService)) as OleMenuCommandService;
66d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      if (null != mcs) {
67d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        // Create the command for the menu item.
68d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        CommandID menuCommandID = new CommandID(GuidList.guidChromeDebugCmdSet, (int)PkgCmdIDList.cmdidAttachToProcess);
69d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        MenuCommand menuItem = new MenuCommand(MenuItemCallback, menuCommandID);
70d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        mcs.AddCommand(menuItem);
71d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      }
72d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    }
73d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    #endregion
74d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
75d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    /// <summary>
76d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    /// This function is the callback used to execute a command when the a menu item is clicked.
77d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    /// See the Initialize method to see how the menu item is associated to this function using
78d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    /// the OleMenuCommandService service and the MenuCommand class.
79d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    /// </summary>
80d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    private void MenuItemCallback(object sender, EventArgs e) {
81d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      // Show a Message Box to prove we were here
82d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      EnvDTE.DTE dte = (EnvDTE.DTE)GetService(typeof(EnvDTE.DTE));
83d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
84d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      IVsUIShell uiShell = (IVsUIShell)GetService(typeof(SVsUIShell));
85d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      Guid clsid = Guid.Empty;
86d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      IntPtr parentHwnd = IntPtr.Zero;
87d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      uiShell.GetDialogOwnerHwnd(out parentHwnd);
88d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
89d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      NativeWindow parentShim = new NativeWindow();
90d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      parentShim.AssignHandle(parentHwnd);
91d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      AttachDialog dialog = new AttachDialog();
92d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      DialogResult result = dialog.ShowDialog(parentShim);
93d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      if (result == DialogResult.OK) {
94d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        foreach (int selected_id in dialog.SelectedItems) {
95d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          foreach (EnvDTE90a.Process4 p in dte.Debugger.LocalProcesses) {
96d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)            System.Diagnostics.Debug.WriteLine("Found process {0}", p.ProcessID);
97d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)            if (p.ProcessID != selected_id)
98d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)              continue;
99d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)            p.Attach();
100d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)            System.Diagnostics.Debug.WriteLine("Attaching to process successful.");
101d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)            break;
102d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          }
103d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        }
104d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      }
105d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    }
106d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
107d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
108