UPDATE: For an updated version of this code which determines if the project is dirty and uses the DTE to prompt the user to save the project, see the blog: How to Determine if a Project isDirty.
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
UPDATE: For an updated version of this code which determines if the project is dirty and uses the DTE to prompt the user to save the project, see the blog: How to Determine if a Project isDirty.
Posted
Nov 13 2008, 03:35 PM
by
Melody