2010-09-25 16 views
8

Mi paquete de Visual Studio requiere el uso de una variable EnvDTE.DTE, pero siempre vuelve a ser nulo. Después de leer muchos hacks, todos dicen usar el método OnShellPropertyChange() (IVsShellPropertyEvents), pero a veces simplemente nunca se dispara, como si mi extensión nunca terminara de cargarse.VSIX: obtener el objeto DTE

Estoy usando VS2010 y comprobando tanto VSSPROPID_Zombie como ShellInitialized - sin trabajo. ? :(

Cualquier idea Este es el código que estoy usando:

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

EDIT: Bajo Experimental Instancia, funciona perfectamente y tarda unos 5 segundos para inicializar Sin embargo, una vez desplegado como VSIX - ella. simplemente no se dispara.

Respuesta

6

veo un par de problemas aquí:

  • que realmente debería estar usando __VSSPROPID4.VSSPROPID_ShellInitialized (definido en Microsoft.VisualStudio.Shell.Interop .10.0) en lugar de -9,083 para facilitar la lectura
  • Usted debe comprobar para ShellInitialized se establece en cierto (aunque la comprobación de zombi va a falsa es correcta)
  • Tenga en cuenta que ShellInitialized cambiará a verdadero una vez ... en el inicio de VS. Verificarlo es el enfoque correcto si su paquete está registrado para cargarse automáticamente al inicio (lo que puede suceder antes de que VS esté listo para funcionar). Sin embargo, la mayoría de los paquetes deben no cargar automáticamente al arrancar, sino cargar según demanda alguna acción del usuario que requiera su código de paquete. Luego puede verificar el servicio DTE en su clase de paquete Método de inicialización.
+0

VSSPROPID4 me dio algunos problemas de ambigüedad, por lo que fui con el número entero por el momento. Cambiaré la condición y veré si funciona ahora, ¡gracias! –

5

Si tiene un componente MEF la forma más fácil de llegar a un objeto DTE es el siguiente

Primera añadir una referencia a Microsoft.VisualStudio.Shell.Immutable.10. a continuación, añadir una Importación de MEF para SVsServiceProvider. Esto objeto tiene un método GetService que puede ser consultada por DTE

[ImportingConstructor] 
public MyComponent(SVsServiceProvider serviceProvider) { 
    _DTE dte = (_DTE)serviceProvider.GetService(typeof(_DTE)); 
} 
+0

no tengo un componente MEF sin embargo. ¿Alguna idea de por qué la propiedad nunca cambia? Es un proyecto VS VMSDK. –

3

sé que ha seleccionado una respuesta ya, pero que se especificaba que quieres ni utilizar el MEF, así que pensé que iba a publicar una alternativa sólo en aras de la exhaustividad ....; 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(); 
     } 
    } 
} 
 
+0

aseado. Gracias :) –

+0

encontró esto también, http://msdn.microsoft.com/en-us/library/68shb4dw%28v=VS.100%29.aspx – Terrance

+0

Cuidado: si está ejecutando más de una instancia de Visual Studio , esto te conseguirá uno de ellos, pero no necesariamente el que estás ejecutando. – RichieHindle

23

Pruebe el siguiente comando:

dte = Package.GetGlobalService(typeof(DTE)) as DTE2; 
+2

Éste funciona para mí, solo tienes que agregar una referencia a Microsoft.VisualStudio.Shell.dll en el proyecto. –

+0

Esto funciona para mí también. Estoy usando el código detrás de XAML UI. –

Cuestiones relacionadas