2015-11-17 38 views
1

我试图通过使用此代码附加一个过程VS:如何自动将进程附加到VS的特定实例?

DTE dte = (DTE)System.Runtime.InteropServices.Marshal.GetActiveObject("VisualStudio.DTE.11.0"); 
EnvDTE.Processes pro = dte.Debugger.LocalProcesses; 

foreach (EnvDTE.Process p in pro) 
{ 
    if (p.ProcessID == num) 
    { 
     p.Attach(); 
     return; 
    } 
    else 
    { 
     continue; 
    } 
} 

我的问题是我无法控制到VS的情况下它得到重视。通常它是我打开的第一个VS窗口。

如何获得所有打开VS实例的列表? 非常感谢您提前!

回答

2

区分正在运行的VS实例的唯一方法是通过已加载的解决方案来选择它们。幸运的是(不是运气),VS也暴露了运行对象表中的EnvDTE.Solution对象。您可以使用Roman's RotView-Win32.exe utility来查看看起来像什么。

,遍历该ROT并返回一些示例代码的所有活动的解决方案:为供试

using System; 
using System.Collections.Generic; 
using System.Runtime.InteropServices; 
using System.Runtime.InteropServices.ComTypes; 

public class VSSolution { 
    public string Name { get; set; } 
    public EnvDTE.Solution Solution { get; set; } 
} 

public static class VSAutomation { 
    public static List<VSSolution> GetRunningSolutions() { 
     var instances = new List<VSSolution>(); 
     // Get running object table reference iterator 
     IRunningObjectTable Rot; 
     int hr = GetRunningObjectTable(0, out Rot); 
     if (hr < 0) throw new COMException("No rot?", hr); 
     IEnumMoniker monikerEnumerator; 
     Rot.EnumRunning(out monikerEnumerator); 

     // And iterate 
     IntPtr pNumFetched = new IntPtr(); 
     IMoniker[] monikers = new IMoniker[1]; 
     while (monikerEnumerator.Next(1, monikers, pNumFetched) == 0) { 
      IBindCtx bindCtx; 
      int hr2 = CreateBindCtx(0, out bindCtx); 
      if (hr < 0) continue; 
      // Check if display ends with ".sln" 
      string displayName; 
      monikers[0].GetDisplayName(bindCtx, null, out displayName); 
      if (displayName.EndsWith(".sln", StringComparison.CurrentCultureIgnoreCase)) { 
       object obj; 
       Rot.GetObject(monikers[0], out obj); 
       if (obj is EnvDTE.Solution) { 
        instances.Add(new VSSolution { Name = displayName, Solution = (EnvDTE.Solution)obj }); 
       } 
       else Marshal.ReleaseComObject(obj); 
      } 
     } 
     return instances; 
    } 
    [DllImport("ole32.dll")] 
    private static extern int CreateBindCtx(uint reserved, out IBindCtx ppbc); 
    [DllImport("ole32.dll")] 
    private static extern int GetRunningObjectTable(int reserved, out IRunningObjectTable prot); 
} 

示例用法:

foreach (var sln in GetRunningSolutions()) { 
     if (sln.Name.EndsWith("ConsoleApplication1.sln")) { 
      var dte = sln.Solution.DTE; 
      // etc... 
     } 
    } 
相关问题