Search code examples
visual-studio-extensionsvs-extensibilityvspackage

Get Add Connection event of Server Explorer window inside VS package


I'm trying to fire some changes on a Menu after a new connection is added or removed from the Server Explorer window on my Visual Studio package. So I'm looking for an event that I can subscribe or any other way that allows me to detect when a new Connection node is added. Does anybody has done something similar?. Any tips are greatly appreciated.


Solution

  • The server explorer is an IVsUIHierarchy similiar to the solution explorer. I haven´t tried it yet, but you should get access to the server explorer hierarchy by requesting an IVsServerExplorer instance, like:

    using Microsoft.VSDesigner.ServerExplorer;
    
    ...
    
    IVsServerExplorer explorer = (IVsServerExplorer) package.GetGlobalService(typeof(IVsServerExplorer));
    IVsUIHierarchy hierarchy;
    if ((hierarchy = explorer as IVsUIHierarchy) != null)
    {
        ...
    }
    

    Once you have the hierarchy you can subscribe for notifications...

    IVsHierarchyEvents eventSink = new ...
    uint cookie = 0;
    int result = hierarchy.AdviseHierarchyEvents(eventSink, out cookie);
    if (result != VSConstants.S_OK)
    {
        ErrorHandler.ThrowOnFailure(result);
    }
    

    You need to provide an IVsHierarchyEvents instance; this object will receive the notifications. I suggest to implement that interface to a listener class, which handles advise and unadvise properly (you need to keep the cookie, in order to unsubscribe from event notification).

    class HierarchyEventsListener : IVsHierarchyEvents, IDisposable
    {
        private readonly IVsUIHierarchy hierarchy;
    
        private uint cookie;
    
        protected HierarchyEventsListener(IVsUIHierarchy hierarchy)
        {
            this.hierarchy = hierarchy;
    
            int hr = this.hierarchy.AdviseHierarchyEvents(this, out cookie);
            ErrorHandler.ThrowOnFailure(hr);
        }
    
        public int OnItemAdded(uint itemidParent, uint itemidSiblingPrev, uint itemidAdded)
        {
            ...
        }
    
        ...
    
        public void Dispose()
        {
            if (this.cookie != 0)
            {
                this.hierarchy.UnadviseHierarchyEvents(this.cookie);
                this.cookie = 0;
            }
        }
    }
    

    In your case you might be interested in the OnItemAdded- and/or OnItemsAppended-method, which allows you to query the newly added item...

    public int OnItemAdded(uint itemidParent, uint itemidSiblingPrev, uint itemidAdded)
    {
        const int Property = (int)__VSHPROPID.VSHPROPID_Caption; // let´s ask for the caption (for instance)
        object value;
        int hr = this.hierarchy.GetProperty(itemidAdded, Property, out value);
        if (hr == VSConstants.S_OK)
        {
            ...
        }
    
        return VSConstants.S_OK;
    }
    

    Maybe you´ll need to play with it to figure out, if the added item is a connection node (guess there´s a type property or such), or not.