【问题标题】:How to automatically attach process to a specific instance of VS?如何自动将进程附加到 VS 的特定实例?
【发布时间】:2015-11-17 12:27:41
【问题描述】:

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

【问题讨论】:

    标签: c# visual-studio envdte attach-to-process


    【解决方案1】:

    区分正在运行的 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...
            }
        }
    

    【讨论】:

      猜你喜欢
      • 2011-08-31
      • 1970-01-01
      • 1970-01-01
      • 2014-11-06
      • 1970-01-01
      • 2020-06-11
      • 1970-01-01
      • 1970-01-01
      • 2012-04-17
      相关资源
      最近更新 更多