Have you noticed, In Visual Studio, when we close the solution, all the build/other messages from the output window are cleared automatically? How is it done? Well, in this post we will see just that. For example, we can monitor events such as OnAfterLoadProject, OnAfterOpenSolution etc and also take actions when they are triggered. To show what we will achieve at the end of this blog, please look at the demo below.

Solution Events

Intersting right? As you can see, we monitor for the events in the solution and log them in the custom toolwindow (called My Tool Window) in the extension. Lets start coding…

Visual Studio SDK provides below two interfaces with which we can achieve this.

Get IVsSolution instance

Through your package instance, you can call GetService method as below to get the instance of IVsSolution.

_solutionService = GetService(typeof(SVsSolution)) as IVsSolution;
if (_solutionService != null)
{
    Common.Instance.Package = this;
    Common.Instance.Solution = _solutionService;
}

In the above example, once I get the instance of IVsSolution, I am storing the package and solution instance, in a singleton class Common. This is utility class for this extension which will help us to access these instances from the view-model our toolwindow uses.

Implement IVsSolutionEvents

As you can see in the demo above, I am showing all the events in a toolwindow. To do that, I am binding a collection to WPF listview with the event names. I have hence implemented this interface to the view-model itself. Ideally you would want to do this in a separate class.

internal class MyControlViewModel : IVsSolutionEvents
{
	//rest of the code
}

Register for notifications of solution events

In the constructor of the view-model, we would start listening for the solution events.

public MyControlViewModel()
{
    uint cookie;
    EventsList = new ObservableCollection<string>();
    Common.Instance.Solution.AdviseSolutionEvents(this, out cookie);
    Common.Instance.SolutionCookie = cookie;
}

In the code above AdviseSolutionEvents registers view-model class as listener. The cookie stores the pointer to the solution event object. We will store this instance Common class so that it can be accessed from Package class later. cookie is required for us to unadvise (unregister) the events later on.

Implement IVsSolutionEvents methods

This interface provides many methods related to solution events. For keeping the blog post short, example method implementation below.

public int OnAfterOpenProject(IVsHierarchy pHierarchy, int fAdded)
{
    EventsList.Add("Triggered OnAfterOpenProject");
    return VSConstants.S_OK;
}

Above code snippet, adds a message to the collection which is bound to the listview.

Unregister from solution events notification

Finally, when package is unloaded or Visual Studio closed, we need to Unadvise from event notification. In the example, we will use the cookie stored in the Common class before and unadvise as below. I am doing this in Package class by overriding Dispose method.

protected override void Dispose(bool disposing)
{
    base.Dispose(disposing);

    if (_solutionService != null && Common.Instance.SolutionCookie != 0)
    {
        _solutionService.UnadviseSolutionEvents(Common.Instance.SolutionCookie);
    }
}

That’s it for this post. You can browse/download the code used to build this demo from GitHub.

Related Posts

About Utkarsh Shigihalli

Utkarsh is passionate about software development and has more than 11 years of work experience. He has developed numerous extensions for Visual Studio and Visual Studio Team Services. He is currently working as a Consultant in the United States.