Dot-Net

不編碼外掛時獲取目前的 EnvDTE 或 IServiceProvider

  • May 2, 2014

我正在編寫一些設計時程式碼。我想使用這個片段:(在這裡找到)

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

問題是這不能編譯。(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 實例。)

這個問題有你正在尋找的答案。

在 Visual C# 2010 中獲取 DTE2 對象的引用

具體來說

https://stackoverflow.com/a/4724924/858142

這是程式碼:

用途:

using System;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using EnvDTE;
using Process = System.Diagnostics.Process;

方法:

[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;
}

正如另一個答案所示,這在調試時不起作用。

引用自:https://stackoverflow.com/questions/10864595