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.


About author
Utkarsh Shigihalli
Utkarsh Shigihalli
Utkarsh is passionate about software development and has experience in the areas of Azure, Azure DevOps, C# and TypeScript. Over the years he has worked as an architect, independent consultant and manager in many countries including India, United States, Netherlands and United Kingdom. He is a Microsoft MVP and has developed numerous extensions for Visual Studio, Visual Studio Code and Azure DevOps.
We Are
  • onlyutkarsh
    Utkarsh Shigihalli
    Microsoft MVP, Technologist & DevOps Coach


  • arora_tarun
    Tarun Arora
    Microsoft MVP, Author & DevOps Coach at Avanade

Do you like our posts? Subscribe to our newsletter!
Our Book