Logo
HOWTO: Pass parameters programmatically to a command from a Visual Studio add-in

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

The IDTCommandTarget.Exec method that add-ins must implement to be called when a command is executed and the CommandEventsClass.BeforeExecute  / CommandEventsClass.AfterExecute events allow to use input/output parameters:

  • The output parameter is sent from the method to the invoker (but Visual Studio ignores it).
  • The input parameter is sent from the invoker to the method. This value can be set:

More Information

The following add-in shows how to execute a command with an input parameter using the DTE.Commands.Raise method. The input parameter value is retrieved in the CommandEventsClass.AfterExecute event handler. The add-ins intercepts the execution of the "Help.About" command and launches it with an input parameter.

using System;
using Extensibility;
using EnvDTE;
using EnvDTE80;

namespace MyAddin1
{
   public class Connect : IDTExtensibility2
   {
      private DTE2 _applicationObject;
      private AddIn _addInInstance;
      private CommandEvents _commandEvents;
      private string _commandGuid;
      private int _commandId;

      public void OnConnection(object application, ext_ConnectMode connectMode, object addInInst, ref Array custom)
      {
         _applicationObject = (DTE2)application;
         _addInInstance = (AddIn)addInInst;

         switch (connectMode)
         {
            case ext_ConnectMode.ext_cm_Startup: 

               // Do nothing. OnStartupComplete will be called when fully initialized.
               break;

            case ext_ConnectMode.ext_cm_AfterStartup:

               Initialize();
               break;
         }
      }

      public void OnStartupComplete(ref Array custom)
      {
         Initialize();
      }

      public void OnDisconnection(ext_DisconnectMode disconnectMode, ref Array custom)
      {
         if (_commandEvents != null)
         {
            _commandEvents.BeforeExecute -= _commandEvents_BeforeExecute;
            _commandEvents.AfterExecute -= _commandEvents_AfterExecute;
            _commandEvents = null;
         }
      }

      private void Initialize()
      {
         EnvDTE.Command command;

         command = _applicationObject.Commands.Item("Help.About");

         _commandGuid = command.Guid;
         _commandId = command.ID;

         _commandEvents = _applicationObject.Events.get_CommandEvents(_commandGuid, _commandId);

         _commandEvents.BeforeExecute += _commandEvents_BeforeExecute;
         _commandEvents.AfterExecute += _commandEvents_AfterExecute;
      }

      private void _commandEvents_BeforeExecute(string Guid, int ID, object CustomIn, object CustomOut, ref bool CancelDefault)
      {
         if (Guid == _commandGuid && ID == _commandId)
         {
            if (CustomIn != null)
            {
               // Ignore, it is the second command execution
            }
            else // It is the first command execution
            {
               _applicationObject.Commands.Raise(Guid, ID, DateTime.Now, null);

               // Cancel this execution of the command
               CancelDefault = true;
            }
         }
      }

      private void _commandEvents_AfterExecute(string Guid, int ID, object CustomIn, object CustomOut)
      {
         if (Guid == _commandGuid && ID == _commandId)
         {
            if (CustomIn == null)
            {
               // Ignore, it is the first command execution
            }
            else // It is the second command execution
            {
               System.Windows.Forms.MessageBox.Show("Command was invoked at this time: " + CustomIn.ToString());
            }
         }
      }

      public void OnAddInsUpdate(ref Array custom)
      {
      }
      public void OnBeginShutdown(ref Array custom)
      {
      }
   }
}


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