在不编码插件时获取当前的EnvDTE或IServiceProvider

Vac*_*ano 11 .net visual-studio-2010 visual-studio envdte visual-studio-extensions

我正在编写一些设计时间代码.我想使用这个片段:( 在这里找到)

var dte = (EnvDTE.DTE) GetService(typeof(EnvDTE.DTE));
if (dte != null)
{
    var solution = dte.Solution;
    if (solution != null)
    {
        string baseDir = Path.GetDirectoryName(solution.FullName);
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是这不能编译.(GetService不是已知的方法调用)我尝试添加Microsoft.VisualStudio.Shell(和Microsoft.VisualStudio.Shell.10.0),但它没有帮助.

在互联网上环顾四周,我发现你需要一个IServiceProvider来调用它.

但所有显示如何使IServiceProvider使用EnvDTE的示例.

所以,要获得当前的EnvDTE,我需要IServiceProvider.但要获得IServiceProvider,我需要一个EnvDTE.(我的桶里有一个洞......)

所以,这是我的问题:

在普通的WPF应用程序中,如何获取EnvDTE 的当前实例

注意:我不是在寻找任何旧的EnvDTE实例.我需要一个用于我当前的Visual Studio实例(我一次运行3-4个Visual Studio实例.)

Qui*_*orn 8

这个问题有你正在寻找的答案.

在Visual C#2010中获取DTE2对象的引用

特别

/sf/answers/330744711/

这是代码:

Usings:

using System;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using EnvDTE;
using Process = System.Diagnostics.Process;
Run Code Online (Sandbox Code Playgroud)

方法:

[DllImport("ole32.dll")]
private static extern void CreateBindCtx(int reserved, out IBindCtx ppbc);
[DllImport("ole32.dll")]
private static extern void GetRunningObjectTable(int reserved,
                                                 out IRunningObjectTable prot);
internal static DTE GetCurrent()
{
   //rot entry for visual studio running under current process.
   string rotEntry = String.Format("!VisualStudio.DTE.10.0:{0}",
                                    Process.GetCurrentProcess().Id);
   IRunningObjectTable rot;
   GetRunningObjectTable(0, out rot);
   IEnumMoniker enumMoniker;
   rot.EnumRunning(out enumMoniker);
   enumMoniker.Reset();
   IntPtr fetched = IntPtr.Zero;
   IMoniker[] moniker = new IMoniker[1];
   while (enumMoniker.Next(1, moniker, fetched) == 0)
   {
       IBindCtx bindCtx;
       CreateBindCtx(0, out bindCtx);
       string displayName;
       moniker[0].GetDisplayName(bindCtx, null, out displayName);
       if (displayName == rotEntry)
       {
           object comObject;
           rot.GetObject(moniker[0], out comObject);
           return (DTE)comObject;
       }
   }
   return null;
}
Run Code Online (Sandbox Code Playgroud)

正如另一个答案所示,这在调试时不起作用.