VSIX:获取DTE对象
-
05-10-2019 - |
题
我的 Visual Studio 包需要使用 EnvDTE.DTE 变量,但它总是返回为 null。在阅读了许多黑客之后,他们都说要使用 OnShellPropertyChange() 方法 (IVsShellPropertyEvents),但有时它永远不会触发 - 就好像我的扩展永远不会完成加载一样。
我正在使用 VS2010 并检查 VSSPROPID_Zombie 和 ShellInitialized - 没有工作。:(
有任何想法吗?这是我正在使用的代码:
public int OnShellPropertyChange(int propid, object var) {
if (propid == -9053 || (int) __VSSPROPID.VSSPROPID_Zombie == propid) { // -9053 = ShellInit
try {
if ((bool) var == false) {
Dte = GetService(typeof (SDTE)) as DTE;
Flow.Dte = Dte;
var shellService = GetService(typeof (SVsShell)) as IVsShell;
if (shellService != null)
ErrorHandler.ThrowOnFailure(shellService.UnadviseShellPropertyChanges(_cookie));
_cookie = 0;
}
} catch {
}
}
return VSConstants.S_OK;
}
编辑:在实验实例下,它运行得很好,大约需要 5 秒来初始化。但是,一旦部署为 VSIX - 它就不会触发。
解决方案
我在这里看到几个问题:
- 为了便于阅读,您确实应该使用 __VSSPROPID4.VSSPROPID_ShellInitialized (在 Microsoft.VisualStudio.Shell.Interop.10.0 中定义)而不是 -9083
- 您应该检查 ShellInitialized 是否设置为 真的 (尽管检查 Zombie 是否变为 false 是正确的)
- 请记住 ShellInitialized 将更改为 true 一次...VS 启动时。如果您的包已注册为在启动时自动加载(这可能在 VS 完全准备好之前发生),则检查它是正确的方法。然而,大多数包应该 不是 在启动时自动加载,而是根据需要包代码的某些用户操作按需加载。然后,您可以在包类的 Initialize 方法中检查 DTE 服务。
其他提示
尝试下面的命令:
dte = Package.GetGlobalService(typeof(DTE)) as DTE2;
如果你有MEF组件来获得到一个DTE
对象的最简单的方法是如下
首先添加到Microsoft.VisualStudio.Shell.Immutable.10的引用。然后添加一个MEF进口的SVsServiceProvider
。这个对象具有可用于查询DTE
一个GetService的方法
[ImportingConstructor]
public MyComponent(SVsServiceProvider serviceProvider) {
_DTE dte = (_DTE)serviceProvider.GetService(typeof(_DTE));
}
我知道你选择的答案已经但是你没有指定你没有想使用MEF,所以我想我会发布一个替代只是为了完整起见....; P
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using EnvDTE;
using EnvDTE80;
namespace DTETesting
{
class Program
{
const string ACTIVE_OBJECT = "VisualStudio.DTE.10.0";
static void Main(string[] args)
{
EnvDTE80.DTE2 MyDte;
MyDte = (EnvDTE80.DTE2)System.Runtime.InteropServices.Marshal.GetActiveObject(ACTIVE_OBJECT);
Console.WriteLine("The Edition is "+MyDte.Edition);
Console.ReadLine();
}
}
}
不隶属于 StackOverflow