locked
EnvDTE.ToolBoxTabs Throws ComException RRS feed

  • Question

  • I'm attempting to programmatically delete a specific ToolBox tab from Visual Studio (part of a custom uninstall package), but I seem to get an intermittent exception thrown in my code.

    Here is the code snippet that sporadically generates the error (the exception is thrown in the private method):

    public void Delete()
    {
    	Window toolbox = dte.Windows.Item(EnvDTE.Constants.vsWindowKindToolbox);
    	ToolBoxTabs tabs = ((ToolBox)toolbox.Object).ToolBoxTabs;
    	dte.ExecuteCommand("View.PropertiesWindow", "");
    
    	// locate the specific Toolbox Tab to delete
    	ToolBoxTab tab = GetToolBoxTab(tabs, "My Custom VS Toolbox Tab");
    	if (tab != null)
    	{
    		tab.Delete();
    	}
    }
    
    /// <summary>
    /// Parses the list of Toolbox Tabs defined in Visual Studio and returns
    /// the Toolbox Tab matching <paramref name="tabName"/>.
    /// </summary>
    private ToolBoxTab GetToolBoxTab(ToolBoxTabs tabs, string tabName)
    {
    	foreach (ToolBoxTab tab in tabs) // <== Throws Exception here
    	{
    		if (english.CompareInfo.Compare(tab.Name, tabName, CompareOptions.IgnoreCase) == 0)
    			return tab;
    	}
    
    	return null;
    }

    The exception that is thrown is the following message:

    "Call was rejected by callee. (Exception from HRESULT: 0x80010001 (RPC_E_CALL_REJECTED))"

    This is thrown within the foreach.

    What is frustrating is that it is only sporadic, and I haven't found a pattern yet.  It happens whether Visual Studio is open or not.

    Anybody have suggestions?

    Thanks!
    Matt


    • Edited by Matt Ring Monday, May 7, 2012 4:29 PM
    Monday, May 7, 2012 4:28 PM

Answers

  • Are you calling this from out of proc or inside VS but off the main thread? 

    If so you need a message filter, when you are trying to make your call (all of DTE is COM, so while the CLR can provide wrapper-ish things that make you able to do things like foreach, really under the covers you are making COM calls) the UI thread in VS is busy and is not accepting incoming RPC calls.  It is sporadic because it depends on what the UI thread is doing when you try to make your call, which is of course non-deterministic.

    See this recent thread:  http://social.msdn.microsoft.com/Forums/en-US/vsx/thread/10da371f-b054-476c-b962-2f24b0de5c23

    Specifically the article he linked about implementing an OLE message filter, and make sure the thread you are doing this on is an STA thread (so apply the STAThread attribute to your main method).

    Ryan

    • Marked as answer by Matt Ring Tuesday, May 8, 2012 8:54 PM
    Monday, May 7, 2012 11:06 PM
  • Thanks Ryan!

    I had already marked main() with [STAThread]; however, I had not implemented a message filter. As defined by the linked thread, I used the code from the MSDN article(direct link: http://msdn.microsoft.com/en-us/library/ms228772.aspx) and this appears to have resolved the sporadic issues.

    Thanks again!

    • Marked as answer by Matt Ring Tuesday, May 8, 2012 8:55 PM
    Tuesday, May 8, 2012 8:54 PM

All replies

  • Are you calling this from out of proc or inside VS but off the main thread? 

    If so you need a message filter, when you are trying to make your call (all of DTE is COM, so while the CLR can provide wrapper-ish things that make you able to do things like foreach, really under the covers you are making COM calls) the UI thread in VS is busy and is not accepting incoming RPC calls.  It is sporadic because it depends on what the UI thread is doing when you try to make your call, which is of course non-deterministic.

    See this recent thread:  http://social.msdn.microsoft.com/Forums/en-US/vsx/thread/10da371f-b054-476c-b962-2f24b0de5c23

    Specifically the article he linked about implementing an OLE message filter, and make sure the thread you are doing this on is an STA thread (so apply the STAThread attribute to your main method).

    Ryan

    • Marked as answer by Matt Ring Tuesday, May 8, 2012 8:54 PM
    Monday, May 7, 2012 11:06 PM
  • Thanks Ryan!

    I had already marked main() with [STAThread]; however, I had not implemented a message filter. As defined by the linked thread, I used the code from the MSDN article(direct link: http://msdn.microsoft.com/en-us/library/ms228772.aspx) and this appears to have resolved the sporadic issues.

    Thanks again!

    • Marked as answer by Matt Ring Tuesday, May 8, 2012 8:55 PM
    Tuesday, May 8, 2012 8:54 PM