Based on this question I\'ve tried the following:
EnvDTE80.DTE2 dte = ServiceProvider.GlobalProvider.GetService(typeof(EnvDTE80.DTE2)) as EnvDTE80.DTE2;
<
The correct way to get the DTE instance from within an extension is to use the way provided by the extensibility API for that extension.
For packages it is using:
base.GetService(typeof(EnvDTE.DTE))
(notice that "base" refers to the MPF Package class so you are using the extensibility API. You are using also the extensibility API if you use the global provider as in your post)
but unrelated to that, is this couple of issues that happen with packages marked to autoload:
1) The returned DTE value will be null when the package is marked to autoload when VS is launched (rather than loading when required)
2) DTE is not null, but some property such as DTE.MainWindow is still null because the VS instance is not fully initialized yet.
To prevent those two cases you must subscribe to a notification that the VS IDE is fully initialized and not in a zombie state. See the horrible hack that you have to use: HOWTO: Get an EnvDTE.DTE instance from a Visual Studio package.
The incorrect way of getting the DTE instance from within an extension is to use COM automation (through the .NET Framework API) instead of using the extensibility API (and it is horrible that the MSDN docs mention this approach):
EnvDTE80.DTE2 dte = (EnvDTE80.DTE2)System.Runtime.InteropServices.Marshal.GetActiveObject("VisualStudio.DTE.12.0");
because GetObject(ProgId) in COM automation (or .NET wrappers such as Marshal.GetActiveObject(ProgId)) are used to attach to a running instance of the required ProgId ("VisualStudio.DTE.12.0") and if you have have more than one running instance your extension could end getting a reference to the other instance!.