HOWTO: Use the IVsMonitorSelection interface from a Visual Studio add-in

Author: Carlos J. Quintero (Microsoft MVP) Applies to: Microsoft Visual Studio 2005
Date: May 2007   Microsoft Visual Studio 2008
Updated: March 2012   Microsoft Visual Studio 2010
      Microsoft Visual Studio 2012


This article explains how to use the IVsMonitorSelection interface from an add-in.

More Information

The IVsMonitorSelection interface of the Visual Studio 2005 SDK or higher can be used to receive notifications of selection events and to retrieve information about UI context. In this example we will use it to retrieve conditions declared in the EnvDTE80.ContextGuids class, for example vsContextGuidDebugging, vsContextGuidDesignMode, vsContextGuidSolutionExists, vsContextGuidSolutionHasMultipleProjects, vsContextGuidSolutionHasSingleProject, vsContextGuidNoSolution, etc.

To get a service from an add-in, see HOWTO: Get a Visual Studio service from an add-in. The IVsMonitorSelection service has an IsCmdUIContextActive method that returns if a context GUID is active. This method receives a dwCmdUICookie integer parameter, not a context GUID, but you can get the cookie of a context GUID using the GetCmdUIContextCookie method.

The following sample creates an add-in, when loaded, reports if a solution is open in the IDE or not, using the vsContextGuidSolutionExists context Guid, rather than the automation model (DTE.Solution.IsOpen):

Imports System
Imports Microsoft.VisualStudio.CommandBars
Imports Extensibility
Imports EnvDTE
Imports EnvDTE80
Imports Microsoft.VisualStudio.Shell.Interop
Imports System.Windows.Forms
Public Class Connect
   Implements Extensibility.IDTExtensibility2
   Public Sub OnConnection(ByVal application As Object, ByVal connectMode _
      As Extensibility.ext_ConnectMode, ByVal addInInst As Object, _
      ByRef custom As System.Array) _
      Implements Extensibility.IDTExtensibility2.OnConnection
      Dim applicationObject As DTE
      Dim monitorSelection As IVsMonitorSelection
      Dim cookie As UInteger
      Dim result As Boolean = False
      Dim active As Integer
         applicationObject = CType(application, DTE)
         Select Case connectMode
            Case ext_ConnectMode.ext_cm_AfterStartup, ext_ConnectMode.ext_cm_Startup
               monitorSelection = DirectCast(GetService(applicationObject, _
                  GetType(IVsMonitorSelection)), IVsMonitorSelection)
               monitorSelection.GetCmdUIContextCookie(New Guid(ContextGuids.vsContextGuidSolutionExists), cookie)
               If monitorSelection.IsCmdUIContextActive(cookie, active) <> 0 Then
                  ' Error. It should not happen
                  If active = 1 Then
                     MessageBox.Show("There is a solution loaded")
                     MessageBox.Show("There is no solution loaded")
                  End If
               End If
         End Select
      Catch e As System.Exception
      End Try
   End Sub
   Public Sub OnDisconnection(ByVal RemoveMode As Extensibility.ext_DisconnectMode, _
      ByRef custom As System.Array) _
      Implements Extensibility.IDTExtensibility2.OnDisconnection
   End Sub
   Public Sub OnStartupComplete(ByRef custom As System.Array) _
      Implements Extensibility.IDTExtensibility2.OnStartupComplete
   End Sub
   Public Sub OnBeginShutdown(ByRef custom As System.Array) _
      Implements Extensibility.IDTExtensibility2.OnBeginShutdown
   End Sub
   Public Sub OnAddInsUpdate(ByRef custom As System.Array) _
       Implements Extensibility.IDTExtensibility2.OnAddInsUpdate
   End Sub
   Private Function GetService(ByVal serviceProvider As Object, ByVal type As System.Type) As Object
      Return GetService(serviceProvider, type.GUID)
   End Function
   Private Function GetService(ByVal serviceProvider As Object, ByVal guid As System.Guid) As Object
      Dim objService As Object = Nothing
      Dim objIServiceProvider As Microsoft.VisualStudio.OLE.Interop.IServiceProvider
      Dim objIntPtr As IntPtr
      Dim hr As Integer
      Dim objSIDGuid As Guid
      Dim objIIDGuid As Guid
      objSIDGuid = guid
      objIIDGuid = objSIDGuid
      objIServiceProvider = CType(serviceProvider, Microsoft.VisualStudio.OLE.Interop.IServiceProvider)
      hr = objIServiceProvider.QueryService(objSIDGuid, objIIDGuid, objIntPtr)
      If hr <> 0 Then
      ElseIf Not objIntPtr.Equals(IntPtr.Zero) Then
         objService = System.Runtime.InteropServices.Marshal.GetObjectForIUnknown(objIntPtr)
      End If
      Return objService
   End Function
End Class

Related articles

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