VSIX: Getting DTE object

10,066

Solution 1

I see a couple of problems here:

  • You really should be using __VSSPROPID4.VSSPROPID_ShellInitialized (defined in Microsoft.VisualStudio.Shell.Interop.10.0) instead of -9083 for readability
  • You should be checking for ShellInitialized being set to true (although checking for Zombie going to false is correct)
  • Keep in mind that ShellInitialized will change to true once...on startup of VS. Checking for it is the right approach if your package is registered to auto-load on startup (which may happen before VS is fully ready to go). However, most packages should not auto-load on startup, but rather load on-demand from some user action requiring your package code. You can then check for the DTE service in your package class Initialize method.

Solution 2

Try the following command:

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

Solution 3

If you have a MEF component the easiest way to get to a DTE object is as follows

First add a reference to Microsoft.VisualStudio.Shell.Immutable.10. Then add a MEF import for SVsServiceProvider. This object has a GetService method which can be queried for DTE

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

Solution 4

I know you selected an answer already but you did specify that you didnt want to use the MEF so I thought I would post an alternative just for the sake of completeness....;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();
        }
    }
}

Share:
10,066
Xeganthy
Author by

Xeganthy

Recently graduated systems engineer, loving .NET since 1.0 and a LINQ fan.

Updated on July 21, 2022

Comments

  • Xeganthy
    Xeganthy almost 2 years

    My Visual Studio package requires the use of an EnvDTE.DTE variable, but it always gets back as null. After reading up on many hacks, all of them say to use the OnShellPropertyChange() method (IVsShellPropertyEvents), but sometimes it just never fires - as if my extension never finishes loading.

    I'm using VS2010 and checking against both VSSPROPID_Zombie and ShellInitialized - no work. :(

    Any ideas? This is the code I'm using:

    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: Under Experimental Instance, it works perfectly and takes about 5 seconds to initialize. However, once deployed as VSIX - it simply doesn't fire.

  • Xeganthy
    Xeganthy over 13 years
    I don't have a MEF component though. Any ideas as to why the property never changes? It's a VS VMSDK project.
  • Xeganthy
    Xeganthy over 13 years
    VSSPROPID4 gave me some ambiguity issues, which is why I went with the integer for now. I'll change the condition and see if it works now - thanks!
  • Terrance
    Terrance about 13 years
  • Scott Mackay
    Scott Mackay almost 12 years
    This one works for me, just have to add a reference to Microsoft.VisualStudio.Shell.dll in the project.
  • RichieHindle
    RichieHindle about 11 years
    Beware: if you're running more than one instance of Visual Studio, this will get you one of them, but not necessarily the one you're running in.
  • Farrukh Waheed
    Farrukh Waheed almost 10 years
    This works for me as well. I'm using in the code behind XAML UI.