How to get an application instance defined by the method OnConnection of an Addin towards an VS Application ?

Hi all,

I have a problem to get the application instance defined in my addin

ex :

Public Sub OnConnection(ByVal application As Object, ByVal _

connectMode As ext_ConnectMode, ByVal addInInst As Object, _

ByRef custom As Array) Implements IDTExtensibility2.OnConnection

_applicationObject = CType(application, DTE2)

_addInInstance = CType(addInInst, AddIn)

End Sub

I want to get this attribute in an other VS application (ex : Windows Application).

In my addin (EVA_CAT) I defined a shared property to get this attribut

ex:

Shared _applicationObject As DTE2

Public Shared ReadOnly Property AppObjt() As DTE2

Get

Return _applicationObject

End Get

End Property

After in my other Application I add the addin assembly (EVA_CAT.dll) in the references

and I call the shared property AppObjt

Imports System

Imports EnvDTE

Imports EnvDTE80

Imports EVA_CAT

Imports Extensibility

Module Main_Template

Sub main()

EVA_IHM.StartupIni(EVA_CAT.Connect.AppObjt)

End Sub

End Module

After to load the addin, I launch the windows application. But AppObjt is nothing.

Can you help me, please.

Leon94



Answer this question

How to get an application instance defined by the method OnConnection of an Addin towards an VS Application ?

  • Dave Waterworth

    Just to make sure i understand you request correctly, are you trying to use the DTE object from your second, external application If so, you must get the DTE instance through the Running Object Table using the process id for the Visual Studio that you want to control. Here is some code that you can use:

    using System;
    using System.Runtime.InteropServices;
    using System.Runtime.InteropServices.ComTypes;
    using EnvDTE;
    using ServiceTestInterfaces;

    namespace RunningObject
    {
    /// <summary>
    /// Summary description for Class1.
    /// </summary>
    class Class1
    {
    public const int WM_SYSCOMMAND = 0x0112;
    public const int SC_CLOSE = 0xF060;

    [DllImport("user32.dll")]
    public static extern int FindWindow(
    string lpClassName, // class name
    string lpWindowName // window name
    );

    [DllImport("user32.dll")]
    public static extern int SendMessage(
    int hWnd, // handle to destination window
    uint Msg, // message
    int wParam, // first message parameter
    int lParam // second message parameter
    );

    [DllImport("ole32.dll")]
    public static extern int GetRunningObjectTable(int reserved, out
    IRunningObjectTable prot);

    [DllImport("ole32.dll")]
    public static extern int CreateBindCtx(int reserved, out IBindCtx
    ppbc);

    object GetMSDEVFromROT(string strProgID)
    {
    IRunningObjectTable prot;
    IEnumMoniker pMonkEnum;
    try
    {
    GetRunningObjectTable(0, out prot);
    prot.EnumRunning(out pMonkEnum);
    pMonkEnum.Reset(); // Churn through enumeration.
    IntPtr fetched = IntPtr.Zero;
    IMoniker[] pmon = new IMoniker[1];
    while (pMonkEnum.Next(1, pmon, fetched) == 0)
    {
    IBindCtx pCtx;
    CreateBindCtx(0, out pCtx);
    string str;
    pmon[0].GetDisplayName(pCtx, null, out str);
    if (str == strProgID)
    {
    object objReturnObject;
    prot.GetObject(pmon[0], out objReturnObject);
    object ide = (object)objReturnObject;
    return ide;
    }
    }
    }
    catch
    {
    return null;
    }
    return null;
    }// End CodeSample

    public object pShell;
    public ErrorInformation hr;
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main(string[] args)
    {

    Class1 o = new Class1();
    foreach (string s in args)
    Console.WriteLine(s);
    if (args.Length > 0 && args[0] == "noload")
    {
    Console.WriteLine("no load specified");
    return;
    }

    //use the moniker of form "!VisualStudio.DTE.7:<PID> for 7.0
    //use the moniker of form "!VisualStudio.DTE.7.1:<PID> for 7.1
    string strMoniker = "!VisualStudio.DTE.8.0:4244";

    o.GetAutomationObject(strMoniker);
    }

    public int GetAutomationObject(string strMoniker)
    {
    _DTE ide = (_DTE)GetMSDEVFromROT(strMoniker);
    return 0;
    }
    }
    }




  • RyanB88

    Well, VB6 supported add-ins only at design-time, not at debug-time or run-time, so I can imagine what pain was for you to make it work the other way...

    Now, VS.NET / VS 2005 fully supports design-time, debug-time and run-time for add-ins:

    - The DTE.Mode property tells you the mode (vsIDEModeDesign, vsIDEModeDebug).

    - You can receive transitions with DTE.DTEEvents.ModeChanged event

    - For some reason (beyond me) there is no vsIDEModeRun value. However, you can assume an initial design mode when your add-in is loaded and then use the DTE.Events.DebuggerEvents to trace the OnEnterBreakMode, OnEnterDesignMode, OnEnterRunMode events and use your own tri-state enum to keep the mode.

    - You can use the IDTCommandTarget.QueryStatus method to disable or make invisible commands (and buttons) of your addin depending on the mode.

    - You can keep a list of created toolwindows and call the property Visible when the IDE changes of mode.

    - Etc.

    The bottom line: much easier than what you are trying to do...



  • Danielz

    Hi,

    That's normal since reusing a physical DLL in different apps does not mean that you can share the data created from that DLL. In your case, when you load the add-in DLL in the VS IDE, it is loaded in an AppDomain created by VS, and when you load the Windows Application, it is loaded in a different AppDomain. Needless to say, they have nothing to do.

    I am not sure what you are trying to do and for what purpose, but the closest is:

    - Your Windows app must get an instance of the DTE object of Visual Studio. It can create a VS.NET instance (via CreateObject("VisualStudio.DTE") or it can get a running instence. See:

    HOWTO: Automating Visual Studio .NET from outside the IDE
    http://www.mztools.com/articles/2005/MZ005.htm

    - Then, it can use the DTE.AddIns collection to get the instance of the AddIn.



  • mcdonaldn

    Hello,

    Thank you for your help.

    I've tried the following:

    I made a simple Add-In with the Add-In Wizarrd. Then added some simple code

    Declaration:

    Private WithEvents m_IDEEvents As EnvDTE.DTEEvents

    and (Declaration section)

    Private Sub m_IDEEvents_ModeChanged(ByVal LastMode As EnvDTE.vsIDEMode) Handles m_IDEEvents.ModeChanged

    MsgBox("Mode changed " & LastMode)

    End Sub

    When using this Add-In the ModeChanged event is never fired when running and stopping!

    Have you got an exeplanation about this bevahiour

    I have to say I'm beginng to fed up with this stuff!

    Thinking moving on Eclipse...I'm currently developping an application that will be used by 500 people.

    I've chosen the .NET platform because I like the idea that you have support when you pay for a licence. I don't like the idea of the open source software because looking for piece of code on the Web and copying and pasting existing stuff isn't exactly my conception of the Job of a software engineer.

    But it seems I've got nothing to loosing....

    Regards

    Leon94


  • bozydar

    Hello,

    Thank you for your answer.
    We can have multiple VS 2005 instances and no a proper way to identy them.
    So let say I change my mind and I would like to retreive the Add-In instance I just loaded within the current VS 2005 environment.
    I've tried without success so far by adding to properties in the connect class:

    Public Shared ReadOnly Property ApplicationObject() As DTE2
    Get
    Return _applicationObject
    End Get
    End Property

    Public Shared ReadOnly Property AddInInstance() As AddIn
    Get
    Return _addInInstance
    End Get
    End Property

    When I'm trying to get them, both variables are set to nothing.

    Regards

    Leon


  • Leonardo Butelli

    Once you get the DTE object as I said, you could call DTE.WIndows.CreateToolwindow, etc, but could you describe your scenario, the purpose of this It is somewhat strange to automate and add-in of VS from a Windows application to tell it to create toolwindows, etc...

  • Igor Grozman

    Hello,

    May be it is time for more explanation about what we are looking for.

    We designed a long time ago, a bunch of add-Ins for VB6.

    These Add-Ins were showing up only at runtime and where disappearing when returning at design time.

    In order to achieve this, the project (let’s call it the Client project) where the add-ins had to be displayed was exporting the VBInstance object to a referenced ActiveX server when Sub main was executing.

    The server application was creating then all the docking windows and toolbar we needed using the CreateToolWindows method. Beside this application was holding APIs for writing into just created docking windows, executing a method living in the Client project by double-clicking on it.

    May be there were a simpler way to do this. Any other idea is welcomed…

    How do we implement the same mechanism with VS 2005 IDE

    Regards

    Leon94


  • fu wing

    Hi,

    The sample

    BUG: Command events fired only to last addin loaded in Visual Studio .NET
    http://www.mztools.com/articles/2004/MZ010.htm 

    that I provided showed how to get events from the IDE.

    So, where is your m_IDEEvents variable initialized Otherwise it is Nothing (null) and of course, you get no events... you should do something like this in the OnConnection method to initialize it:

    m_IDEEvents = _applicationObject.Events.DTEEvents

    Once initialized, you should get events.

     

     



  • Nitin Sharma22

    Thanks,

    But Can you give me an example please


  • GTH

    About the usage of IDTCommandTarget.QueryStatus:

    HOWTO: Adding buttons, commandbars and toolbars to Visual Studio .NET from an add-in
    http://www.mztools.com/articles/2005/MZ003.htm

    About creating toolwindows:

    HOWTO: Create a dockable toolwindow from a Visual Studio .NET add-in
    http://www.mztools.com/articles/2006/MZ007.htm

    About getting events from DTE:

    BUG: Command events fired only to last addin loaded in Visual Studio .NET
    http://www.mztools.com/articles/2004/MZ010.htm

    The samples may not be very specific to your actual problem, but show some code and should get you started. You can post specific questions about problems that you encounter.



  • Alvin Kuiper

    Thanks for your help but i need of this intance application to launch the command "CreateToolWindows2" in an Windows application


  • How to get an application instance defined by the method OnConnection of an Addin towards an VS Application ?