HOWTO: Migrate macro events to a Visual Studio add-in

Author: Carlos J. Quintero (Microsoft MVP) Applies to: Microsoft Visual Studio 2012
Date: July 2013    

Visual Studio 2012 removed support for macros. This article shows how to migrate your existing macro events of Visual Studio 2010 (or lower version) to a Visual Studio 2012 add-in.

More Information

Visual Studio 2010 and lower provided a macro module named "EnvironmentEvents" where you could add event handlers for environment events:

Language: VB.NET   Copy Code Copy Code (IE only)
Public Module EnvironmentEvents

#Region "Automatically generated code, do not modify"
   'Automatically generated code, do not modify
   'Event Sources Begin
   <System.ContextStaticAttribute()> Public WithEvents DTEEvents As EnvDTE.DTEEvents
   <System.ContextStaticAttribute()> Public WithEvents DocumentEvents As EnvDTE.DocumentEvents
   <System.ContextStaticAttribute()> Public WithEvents WindowEvents As EnvDTE.WindowEvents
   <System.ContextStaticAttribute()> Public WithEvents TaskListEvents As EnvDTE.TaskListEvents
   <System.ContextStaticAttribute()> Public WithEvents FindEvents As EnvDTE.FindEvents
   <System.ContextStaticAttribute()> Public WithEvents OutputWindowEvents As EnvDTE.OutputWindowEvents
   <System.ContextStaticAttribute()> Public WithEvents SelectionEvents As EnvDTE.SelectionEvents
   <System.ContextStaticAttribute()> Public WithEvents BuildEvents As EnvDTE.BuildEvents
   <System.ContextStaticAttribute()> Public WithEvents SolutionEvents As EnvDTE.SolutionEvents
   <System.ContextStaticAttribute()> Public WithEvents SolutionItemsEvents As EnvDTE.ProjectItemsEvents
   <System.ContextStaticAttribute()> Public WithEvents MiscFilesEvents As EnvDTE.ProjectItemsEvents
   <System.ContextStaticAttribute()> Public WithEvents DebuggerEvents As EnvDTE.DebuggerEvents
   <System.ContextStaticAttribute()> Public WithEvents ProjectsEvents As EnvDTE.ProjectsEvents
   <System.ContextStaticAttribute()> Public WithEvents TextDocumentKeyPressEvents As EnvDTE80.TextDocumentKeyPressEvents
   <System.ContextStaticAttribute()> Public WithEvents CodeModelEvents As EnvDTE80.CodeModelEvents
   <System.ContextStaticAttribute()> Public WithEvents DebuggerProcessEvents As EnvDTE80.DebuggerProcessEvents
   <System.ContextStaticAttribute()> Public WithEvents DebuggerExpressionEvaluationEvents As EnvDTE80.DebuggerExpressionEvaluationEvents
   'Event Sources End
   'End of automatically generated code
#End Region
    Private Sub DocumentEvents_DocumentOpened(ByVal Document As EnvDTE.Document) Handles DocumentEvents.DocumentOpened

       System.Windows.Forms.MessageBox.Show("Opened " & Document.Name & " on " & DTE.Name & " " & DTE.Edition & " " & DTE.Version)

    End Sub

End Module  

Since Visual Studio 2012 and higher removed support for macros, you can create an add-in with the same functionality as follows:

  • Launch Visual Studio 2012 or higher.
  • Click the "FILE", "New", "Project..." menu.
  • Go to the node "Templates", "Other Project Types", "Extensibility".
  • Select the "Visual Studio Add-in" template and give the add-in a name, for example, "MyMacrosAddin".
  • In the page 1 of 6, click the option "Create an Add-in using Visual Basic".
  • In the page 4 of 6, click the option "I would like my Add-in to load when the host application starts".
  • Replace the code of the Connect.vb file by the code below.


  • Notice that the Connect class of the add-in implements the IDTExtensibility2 interface, which provides methods to be called by Visual Studio when the add-in is loaded (OnConnection, OnStartupComplete), unloaded (OnBeginShutdown, OnDisconnection), etc.

  • The "application" parameter of the OnConnection method is converted to the EnvDTE80.DTE2 type and stored in a class variable named DTE, so that your macro methods don't need modification.

The code of the Connect class is the following:

Language: VB.NET   Copy Code Copy Code (IE only)
Imports System
Imports System.Collections.Generic
Imports Extensibility
Imports EnvDTE
Imports EnvDTE80

Public Class Connect
   Implements IDTExtensibility2

   Private DTE As EnvDTE80.DTE2
   Private WithEvents DocumentEvents As EnvDTE.DocumentEvents

   Public Sub OnConnection(ByVal application As Object, ByVal connectMode As ext_ConnectMode, _
      ByVal addInInst As Object, ByRef custom As Array) Implements IDTExtensibility2.OnConnection

      Me.DTE = CType(application, EnvDTE80.DTE2)

      Select Case connectMode

         Case ext_ConnectMode.ext_cm_AfterStartup

            ' The add-in has been loaded after Visual Studio was loaded. Since Visual Studio
            ' is fully initialized, we can initialize the add-in

         Case ext_ConnectMode.ext_cm_Startup

            ' The add-in has been loaded with Visual Studio. Do nothing until Visual Studio 
            ' is fully initialized (the OnStartupComplete method will be called)

         Case ext_ConnectMode.ext_cm_UISetup

            ' Do nothing in this case

      End Select

   End Sub

   Public Sub OnStartupComplete(ByRef custom As Array) Implements IDTExtensibility2.OnStartupComplete


   End Sub

   Private Sub InitializeAddIn()

      Me.DocumentEvents = Me.DTE.Events.DocumentEvents

   End Sub

   Public Sub OnDisconnection(ByVal disconnectMode As ext_DisconnectMode, ByRef custom As Array) _
      Implements IDTExtensibility2.OnDisconnection

      Me.DocumentEvents = Nothing

   End Sub

   Public Sub OnAddInsUpdate(ByRef custom As Array) Implements IDTExtensibility2.OnAddInsUpdate
   End Sub

   Public Sub OnBeginShutdown(ByRef custom As Array) Implements IDTExtensibility2.OnBeginShutdown
   End Sub

   Private Sub DocumentEvents_DocumentOpened(Document As Document) Handles DocumentEvents.DocumentOpened

      System.Windows.Forms.MessageBox.Show("Opened " & Document.Name & " on " & DTE.Name & " " & DTE.Edition & " " & DTE.Version)

   End Sub

End Class

Related articles

Go back to the 'Resources for Visual Studio .NET extensibility' section for more articles like this