Want more features on Pastebin? Sign Up, it's FREE!
Guest

Dynamic VS Attach to Process

By: a guest on Nov 3rd, 2011  |  syntax: C#  |  size: 6.74 KB  |  views: 327  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. using System.IO;
  2. using EnvDTE;
  3. using DTEProcess = EnvDTE.Process;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Diagnostics;
  7. using Process = System.Diagnostics.Process;
  8. using System.Linq;
  9. using System.Runtime.InteropServices;
  10. using System.Runtime.InteropServices.ComTypes;
  11. using System.Runtime.InteropServices;
  12.  
  13. using System.Diagnostics;
  14.  
  15. namespace AppController
  16. {
  17.     #region Classes
  18.  
  19.     public class VisualStudioAttacher
  20.     {
  21.         #region Public Methods
  22.  
  23.         [DllImport("User32")]
  24.         private static extern int ShowWindow(int hwnd, int nCmdShow);
  25.  
  26.         [DllImport("ole32.dll")]
  27.         public static extern int CreateBindCtx(int reserved, out IBindCtx ppbc);
  28.  
  29.         [DllImport("ole32.dll")]
  30.         public static extern int GetRunningObjectTable(int reserved, out IRunningObjectTable prot);
  31.  
  32.  
  33.         [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  34.         public static extern bool SetForegroundWindow(IntPtr hWnd);
  35.         [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  36.         public static extern IntPtr SetFocus(IntPtr hWnd);
  37.  
  38.  
  39.         public static string GetSolutionForVisualStudio(Process visualStudioProcess)
  40.         {
  41.             _DTE visualStudioInstance;
  42.             if (TryGetVsInstance(visualStudioProcess.Id, out visualStudioInstance))
  43.             {
  44.                 try
  45.                 {
  46.                     return visualStudioInstance.Solution.FullName;
  47.                 }
  48.                 catch (Exception)
  49.                 {
  50.                 }
  51.             }
  52.             return null;
  53.         }
  54.  
  55.         public static Process GetAttachedVisualStudio(Process applicationProcess)
  56.         {
  57.             IEnumerable<Process> visualStudios = GetVisualStudioProcesses();
  58.  
  59.             foreach (Process visualStudio in visualStudios)
  60.             {
  61.                 _DTE visualStudioInstance;
  62.                 if (TryGetVsInstance(visualStudio.Id, out visualStudioInstance))
  63.                 {
  64.                     try
  65.                     {
  66.                         foreach (Process debuggedProcess in visualStudioInstance.Debugger.DebuggedProcesses)
  67.                         {
  68.                             if (debuggedProcess.Id == applicationProcess.Id)
  69.                             {
  70.                                 return debuggedProcess;
  71.                             }
  72.                         }
  73.                     }
  74.                     catch (Exception)
  75.                     {
  76.                     }
  77.                 }
  78.             }
  79.             return null;
  80.         }
  81.  
  82.         public static void AttachVisualStudioToProcess(Process visualStudioProcess, Process applicationProcess)
  83.         {
  84.             _DTE visualStudioInstance;
  85.  
  86.             if (TryGetVsInstance(visualStudioProcess.Id, out visualStudioInstance))
  87.             {
  88.                 //Find the process you want the VS instance to attach to...
  89.                 DTEProcess processToAttachTo = visualStudioInstance.Debugger.LocalProcesses.Cast<DTEProcess>().FirstOrDefault(process => process.ProcessID == applicationProcess.Id);
  90.  
  91.                 //Attach to the process.
  92.                 if (processToAttachTo != null)
  93.                 {
  94.                     processToAttachTo.Attach();
  95.                    
  96.                     ShowWindow((int)visualStudioProcess.MainWindowHandle, 3);
  97.                     SetForegroundWindow(visualStudioProcess.MainWindowHandle);
  98.                 }
  99.                 else
  100.                 {
  101.                     throw new InvalidOperationException("Visual Studio process cannot find specified application '" + applicationProcess.Id + "'");
  102.                 }
  103.             }
  104.         }
  105.  
  106.         public static Process GetVisualStudioForSolutions(List<string> solutionNames)
  107.         {
  108.             foreach (string solution in solutionNames)
  109.             {
  110.                 Process visualStudioForSolution = GetVisualStudioForSolution(solution);
  111.                 if (visualStudioForSolution != null)
  112.                 {
  113.                     return visualStudioForSolution; ;
  114.                 }
  115.             }
  116.             return null;
  117.         }
  118.  
  119.  
  120.         public static Process GetVisualStudioForSolution(string solutionName)
  121.         {
  122.             IEnumerable<Process> visualStudios = GetVisualStudioProcesses();
  123.  
  124.             foreach (Process visualStudio in visualStudios)
  125.             {
  126.                 _DTE visualStudioInstance;
  127.                 if (TryGetVsInstance(visualStudio.Id, out visualStudioInstance))
  128.                 {
  129.                     try
  130.                     {
  131.                         string actualSolutionName = Path.GetFileName(visualStudioInstance.Solution.FullName);
  132.  
  133.                         if (string.Compare(actualSolutionName, solutionName, StringComparison.InvariantCultureIgnoreCase) == 0)
  134.                         {
  135.                             return visualStudio;
  136.                         }
  137.                     }
  138.                     catch (Exception)
  139.                     {
  140.                     }
  141.                 }
  142.             }
  143.             return null;
  144.         }
  145.  
  146.         #endregion
  147.  
  148.         #region Private Methods
  149.  
  150.         private static IEnumerable<Process> GetVisualStudioProcesses()
  151.         {
  152.             Process[] processes = Process.GetProcesses();
  153.             return processes.Where(o => o.ProcessName.Contains("devenv"));
  154.         }
  155.  
  156.         private static bool TryGetVsInstance(int processId, out _DTE instance)
  157.         {
  158.             IntPtr numFetched = IntPtr.Zero;
  159.             IRunningObjectTable runningObjectTable;
  160.             IEnumMoniker monikerEnumerator;
  161.             IMoniker[] monikers = new IMoniker[1];
  162.  
  163.             GetRunningObjectTable(0, out runningObjectTable);
  164.             runningObjectTable.EnumRunning(out monikerEnumerator);
  165.             monikerEnumerator.Reset();
  166.  
  167.             while (monikerEnumerator.Next(1, monikers, numFetched) == 0)
  168.             {
  169.                 IBindCtx ctx;
  170.                 CreateBindCtx(0, out ctx);
  171.  
  172.                 string runningObjectName;
  173.                 monikers[0].GetDisplayName(ctx, null, out runningObjectName);
  174.  
  175.                 object runningObjectVal;
  176.                 runningObjectTable.GetObject(monikers[0], out runningObjectVal);
  177.  
  178.                 if (runningObjectVal is _DTE && runningObjectName.StartsWith("!VisualStudio"))
  179.                 {
  180.                     int currentProcessId = int.Parse(runningObjectName.Split(':')[1]);
  181.  
  182.                     if (currentProcessId == processId)
  183.                     {
  184.                         instance = (_DTE)runningObjectVal;
  185.                         return true;
  186.                     }
  187.                 }
  188.             }
  189.  
  190.             instance = null;
  191.             return false;
  192.         }
  193.  
  194.         #endregion
  195.     }
  196.  
  197.     #endregion
  198. }
  199.  
  200.  
clone this paste RAW Paste Data