Solution Events in VS11 AddIns

For those of you having problems with your addin in Visual Studio 11 where the EnvDte.SolutionEvents is not fired: I have the solution!

It’s all about interfaces

Forget about the (old school?) SolutionEvents. By digging around in the Microsoft.VisualStudio.Shell.Interop namespace I stumpled upon the IVsSolutionEvents interface! Check out the following methods:

  • OnAfterCloseSolution
  • OnAfterLoadProject
  • OnAfterOpenProject
  • OnAfterOpenSolution
  • OnBeforeCloseProject
  • OnBeforeCloseSolution
  • OnBeforeUnloadProject
  • OnQueryCloseProject
  • OnQueryCloseSolution
  • OnQueryUnloadProject
  • And subscription of course

    But how do I tell VS I am interested in being called, hence I am implementing the interface? Within the OnConnection method from the IDTExtensibility2 interface you can subscribe yourself with the following piece of code:

    public void OnConnection(object Application, ext_ConnectMode ConnectMode, object AddInInst, ref Array custom)        
    {
        using (ServiceProvider sp = new ServiceProvider(
    			(Microsoft.VisualStudio.OLE.Interop.IServiceProvider)_applicationObject))
        {
            var solution = sp.GetService(typeof(SVsSolution)) as IVsSolution;
            if (solution != null)
            {
                if (solution.AdviseSolutionEvents(this, out _solutionEventsCookie) != VSConstants.S_OK)
                {
                    MessageBox.Show("Something went wrong.");
                }
            }
        }
    }
    
    public void OnDisconnection(ext_DisconnectMode RemoveMode, ref Array custom)
    {
        using (ServiceProvider sp = new ServiceProvider(
    			(Microsoft.VisualStudio.OLE.Interop.IServiceProvider)_applicationObject))
        {
            var solution = sp.GetService(typeof(SVsSolution)) as IVsSolution;
            if (solution != null)
            {
                if (solution.UnadviseSolutionEvents(_solutionEventsCookie) != VSConstants.S_OK)
                {
                    MessageBox.Show("Something went wrong.");
                }
            }
        }
    }
    

    Within each method you can easily return VSConstants.S_OK when everything is fine.

    Credits

    Thanks to Elisha for helping me out on how to subscribe using this interface.