如何将进程自动附加到VS的特定实例

本文关键字:VS 实例 进程 | 更新日期: 2023-09-27 18:22:10

我正试图使用以下代码将进程附加到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实例的列表?提前非常感谢!

如何将进程自动附加到VS的特定实例

区分正在运行的VS实例的唯一方法是根据它们加载的解决方案来选择它们。幸运的是(不是幸运的),VS还公开了运行对象表中的EnvDTE.Solution对象。您可以使用Roman的RotView-Win32.exe实用程序来查看它的外观。

一些迭代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...
        }
    }