Monitoring and Controlling the IDE- Catching the File.Exit and other events

You may wish to monitor a user’s actions in the IDE and respond to or cancel them.  I found a great article and sample which shows how to catch any and all events.  One common request that this could be used to address is responding to the user exiting out of the IDE.   

When the IDE is launched from the host, exiting the IDE really hides it instead of closing it, leaving the vsta.exe process running, and the user is not prompted to save changes.  Below is some code added to the ShapeAppMacroRecordingCSharp sample which catches the File.Exit event, prompts the user to save the project, and quits the IDE bringing down the vsta.exe process.  An additional method is also included which catches all events, this is very useful for determining the GUID and ID of a specific event you are interested in.

This workaround is based on an article by Carlos J. Quintero, HOWTO: Capturing commands events from Visual Studio .NET add-ins and a sample from CodeProject, Add-in to attach ASP.NET debugger. 


private
void EnsureIDE()
{   /*unchanged code omitted*/

   //get and subscribe to all events prior to execution
  
EnvDTE.CommandEvents commandEvents = dte.Events.get_CommandEvents("{00000000-0000-0000-0000-000000000000}", 0);

   commandEvents.BeforeExecute += new EnvDTE._dispCommandEvents_BeforeExecuteEventHandler(commandEvents_BeforeExecute);

   //get and subscribe to the File.Exit event prior to execution
   EnvDTE.CommandEvents exitCommand = dte.Events.get_CommandEvents("{5EFC7975-14BC-11CF-9B2B-00AA00573819}", 229); 

   exitCommand.BeforeExecute += new EnvDTE._dispCommandEvents_BeforeExecuteEventHandler(exitCommand_BeforeExecute); 
}

void exitCommand_BeforeExecute(string Guid, int ID, object CustomIn, object CustomOut, ref bool CancelDefault)
{
   //Project.IsDirty is always false, so use .Saved which starts true
   if (this.macroProject.Saved == true)
   {
      //prompt the user to save the project
      DialogResult answer = MessageBox.Show("Do you want to save changes to " + this.macroProject.Name + "?", "ShapeAppCSharp", MessageBoxButtons.YesNo); 

      if (answer == DialogResult.Yes)
      {
         this.macroProject.Save(null);
      }

      //change the saved state
      this.macroProject.Saved = false;
   }

   //quit the IDE
   this.dte.Quit();           
}

void commandEvents_BeforeExecute(string Guid, int ID, object CustomIn, object CustomOut, ref bool CancelDefault)
{
   EnvDTE.Command objCommand = default(EnvDTE.Command);
   string sCommandName = null; 

   //break here to check out any commands you are interested in
   objCommand = dte.Commands.Item(Guid, ID); 

   if ((objCommand != null))
   {
      sCommandName = objCommand.Name; 

      if (sCommandName.Equals("Something.WorthWatching"))
      {
         //do something
      }
   }
}

 

Visual Basic:

AddHandler Me.mDTE.Events.CommandEvents("{5EFC7975-14BC-11CF-9B2B-00AA00573819}", 229).BeforeExecute, AddressOf exitCommand_BeforeExecute

Private Sub exitCommand_BeforeExecute(ByVal Guid As String, ByVal ID As Integer, ByVal CustomIn As Object, ByVal CustomOut As Object, ByRef CancelDefault As Boolean)

 

   'Project.IsDirty is alwyas false, so use .Saved which starts true

   If Me.macroProject.Saved Then

 

      'prompt the user to save the project

      Dim answer As System.Windows.Forms.DialogResult = System.Windows.Forms.MessageBox.Show("Do you want to save changes to " + Me.macroProject.Name + "?", HostId, System.Windows.Forms.MessageBoxButtons.YesNo)

 

      If answer = System.Windows.Forms.DialogResult.Yes Then

         Me.macroProject.Save(Nothing)

      End If

 

      'change the saved state

      Me.macroProject.Saved = False

 

   End If

 

   'quit the IDE

   Me.mDTE.Quit() 

End Sub

 

 


Posted Nov 13 2008, 03:35 PM by Melody
Filed under: , , ,
Copyright Summit Software Company, 2008. All rights reserved.