2015-11-17 40 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... 
     } 
    } 
相關問題