Wish you all VS extenders a belated Merry Christmas. As usual I am a little late and my apologies for that. I hope you had a merry Christmas and a great time with your family and friends. I had a great time too. However, I will remember this season for one problem that kept me intrigued for quite some time. It seemed weird that my automation object (ThreadingModel - Both) returned by the GetAutomationObject method was being created on UI thread (STA) but the method calls were coming on MTA threads. Common COM sense told me that this was not right. This managed component was appropriately marked as ThreadingModel=Both in the registry. Because of that, I would get InvalidCastExceptions when attempting to get ILocalRegistry interface. SLocalRegistry is meant to be used only from the main UI thread. Hence, the exception was appropriate. This exception had me puzzled for quite some time as I was expecting the method call to come on STA thread given that it was created in one.
Little did I know about CLR's marshalling glue that makes managed COM objects behave *as if* they aggregate the Free Threaded Marshaler (FTM). They do not really aggregate it but behavior is similar. The CLR implements IMarshal on behalf of all managed objects that do not provide their own implementation. This IMarshal implementation is what provides functionality similar to the one FTM would do. So be aware of this when you are using/implementing managed COM components in context of VS integration. To get to the native COM component like behavior you can derive the class from System.EnterpriseServices.ServicedComponent. The CLR then strictly applies the the registered Threading model and context constraints.
Thanks to Chris Brumme's blog on this. Hope this was helpful. Wish you all a very Happy New Year with lots of fun filled days ahead extending Visual Studio.