The MS VSTA team responds to this issue as follows:
In the 3rd proc scenario (Non-Destructive Seamless Debugging) the context is a transparent proxy created in the 3rd proc, not in the host’s process. When the 3rd proc is destroyed, so is this context.
So, it looks like all the host has to do is catch the exception. All the cleanup is done automatically when the 3rd proc is destroyed:.
Further details:
The context throws an exception [because]as the same is created as a remote context in an external process which no longer exists when we do a ctrl Alt break to stop debugging. (Refer to the RemoteProcessCreation image for marked process that is created behind the scenes to support the debugging scenario)
Best way to verify the same is to have System.Runtime.Remoting.RemotingServices.IsTransparentProxy(context.contract).
In the Alt F11 scenario/ NDD case the debugging happens via the add in load in an external process
The context created here is a transparent proxy here(created in remote process) and unload is attempted in AddInMacroExited event that gets fired after process dies (external process that loads the addin), so context is no longer valid.
=End of Microsoft comments=
=======================================
Summit’s Repro Steps:
1. Open ShapeAppAdvancedCSharp SDK Sample project in VS
2. In extension.cs, add this line to AddInProcessExitedMacro event handler:
private void AddInProcessExitedMacro(object sender, EventArgs args)
{
System.Diagnostics.Debug.Assert(this.isDebugging);
try
{
UnloadContext(this.macroContext);çAdd this line
this.addInProcess = null;
this.addInController = null;
3. In extension.cs, comment out the ‘catch’ block so that the thrown exception is seen
private void UnloadContext(Context context)
{
try
{
foreach (AddInCollection coll in context)
{
foreach (AddIn a in coll)
{
if (a.IsLoaded)
a.Unload(TimeSpan.FromSeconds(5));
}
}
}
//catch ç Comment out this block
//{
// // Ignore the exception. Throw in the case where the hosting process is shut down.
//}
finally
{
context = null;
}
}
4. Run application from VS, Alt + F11 (or select menu to show the VSTA IDE), open default macro project, and set a breaakpoint in the startup event:
private void TheApplication_Startup(object sender, EventArgs e)
{ç Set Breakpoint here from inside VSTA IDE
5. F5 to Run/Debug the addin from the VSTA IDE
6. When the breakpoint in the macro/addin’s startup event is hit in VSTA IDE, Stop debugging (Ctl + Alt + Break).
7. Exception: Unable to cast COM object of type 'System.__ComObject' to interface type 'Microsoft.VisualStudio.Tools.Applications.ComChannel.Internal.IComRemotingServer'. This operation failed because the QueryInterface call on the COM component for the interface with IID…
====================
I’m not sure that this is helpful to you because I believe that you are looking for a way to explicitly unload the extern proc debugged addin.
So to do any addin unhook/ cleanup, we must catch the addin/debugger before AddInProcessExitedMacro, because, at this event, the external proc is already killed.
I looked at other events in the DTE and the only one that looks like it would work so far is the CommandBar click event :
private EnvDTE.CommandBarEvents commandBarEvents;
Track down which commandbar button stops debugging and hookup the click event
this.commandBarEvents = dte.Events.get_CommandBarEvents(...)
this.commandBarEvents.Click +=new EnvDTE._dispCommandBarControlEvents_ClickEventHandler(commandBarEvents_Click);
When the stop debug button is clicked, or matching accel key, the click event should allow the host app to do any necessary unhooking/addin teardown. This could be used in conjunction with debugger stopped status from the dte to determine that the user stopped the debug session.
-G