What is the difference between these methods of getting DTE2 (Visual Studio 2013)

前端 未结 1 557
清酒与你
清酒与你 2021-02-10 12:00

Based on this question I\'ve tried the following:

EnvDTE80.DTE2 dte = ServiceProvider.GlobalProvider.GetService(typeof(EnvDTE80.DTE2)) as EnvDTE80.DTE2;
<         


        
相关标签:
1条回答
  • 2021-02-10 12:41

    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 macros it was the global DTE instance.
    • For add-ins it was the instance passed in the OnConnection method of the IDTExtensibility2 interface that add-ins had to implement.
    • 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!.

    0 讨论(0)
提交回复
热议问题