Logo
HOWTO: Get solution events from a Visual Studio package

Author: Carlos J. Quintero (Microsoft MVP) Applies to: Microsoft Visual Studio 2010
Date: September 2014   Microsoft Visual Studio 2012
      Microsoft Visual Studio 2013
Introduction

Using the automation model (EnvDTE) you can get solution events using DTE.Solution.Events.SolutionEvents. Although a package can use also the DTE object, the Microsoft.VisualStudio.Shell.Interop.IVsSolutionEvents interface can be used to avoid the automation model.

More Information

The following sample shows a package that gets solution events using a class that implements the IVsSolutionEvents interface and the AdviseSolutionEvents method of the IVsSolution interface. Notice that the package is set to autoload when a solution exists.

Language: C#   Copy Code Copy Code (IE only)
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.OLE.Interop;
using Microsoft.VisualStudio.Shell;

namespace Company.VSPackageSolutionEvents
{
   [PackageRegistration(UseManagedResourcesOnly = true)]
   [InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)]
   [Guid(GuidList.guidVSPackageSolutionEventsPkgString)]
   [ProvideAutoLoad(VSConstants.UICONTEXT.SolutionExists_string)]
   public sealed class VSPackageSolutionEventsPackage : Package
   {
      private IVsSolution _solution;
      private SolutionEventsHandler _solutionEventsHandler;
      private uint _solutionEventsCookie = 0;

      public VSPackageSolutionEventsPackage()
      {
      }

      protected override void Initialize()
      {
         base.Initialize();

         _solution = base.GetService(typeof(SVsSolution)) as IVsSolution;

         if (_solution != null)
         {
            _solutionEventsHandler = new SolutionEventsHandler(this);

            _solution.AdviseSolutionEvents(_solutionEventsHandler, out _solutionEventsCookie);
         }
      }

      protected override void Dispose(bool disposing)
      {
         if (_solutionEventsCookie != 0)
         {
            _solution.UnadviseSolutionEvents(_solutionEventsCookie);
            _solutionEventsCookie = 0;
         }
         _solutionEventsHandler = null;

         base.Dispose(disposing);
      }

      internal void HandleSolutionEvent(string eventName)
      {
         Debug.WriteLine(eventName);
      }
   }

   internal class SolutionEventsHandler : IVsSolutionEvents
   {
      private VSPackageSolutionEventsPackage _package;

      internal SolutionEventsHandler(VSPackageSolutionEventsPackage package)
      {
         _package = package;
      }

      public int OnAfterCloseSolution(object pUnkReserved)
      {
         _package.HandleSolutionEvent("OnAfterCloseSolution");
         return VSConstants.S_OK;
      }

      public int OnAfterLoadProject(IVsHierarchy pStubHierarchy, IVsHierarchy pRealHierarchy)
      {
         _package.HandleSolutionEvent("OnAfterLoadProject");
         return VSConstants.S_OK;
      }

      public int OnAfterOpenProject(IVsHierarchy pHierarchy, int fAdded)
      {
         _package.HandleSolutionEvent("OnAfterOpenProject");
         return VSConstants.S_OK;
      }

      public int OnAfterOpenSolution(object pUnkReserved, int fNewSolution)
      {
         _package.HandleSolutionEvent("OnAfterOpenSolution");
         return VSConstants.S_OK;
      }

      public int OnBeforeCloseProject(IVsHierarchy pHierarchy, int fRemoved)
      {
         _package.HandleSolutionEvent("OnBeforeCloseProject");
         return VSConstants.S_OK;
      }

      public int OnBeforeCloseSolution(object pUnkReserved)
      {
         _package.HandleSolutionEvent("OnBeforeCloseSolution");
         return VSConstants.S_OK;
      }

      public int OnBeforeUnloadProject(IVsHierarchy pRealHierarchy, IVsHierarchy pStubHierarchy)
      {
         _package.HandleSolutionEvent("OnBeforeUnloadProject");
         return VSConstants.S_OK;
      }

      public int OnQueryCloseProject(IVsHierarchy pHierarchy, int fRemoving, ref int pfCancel)
      {
         _package.HandleSolutionEvent("OnQueryCloseProject");
         return VSConstants.S_OK;
      }

      public int OnQueryCloseSolution(object pUnkReserved, ref int pfCancel)
      {
         _package.HandleSolutionEvent("OnQueryCloseSolution");
         return VSConstants.S_OK;
      }

      public int OnQueryUnloadProject(IVsHierarchy pRealHierarchy, ref int pfCancel)
      {
         _package.HandleSolutionEvent("OnQueryUnloadProject");
         return VSConstants.S_OK;
      }
   }
}


Go to the 'Visual Studio Extensibility (VSX)' web site for more articles like this (Articles section)