.NET Forum / Visual Studio.NET / Extensibility / December 2005
IvsMonitorSelection.GetCurrentSelection returns Interface not regi
|
|
Thread rating:  |
Notre Poubelle - 08 Nov 2005 00:59 GMT Hello,
My package is using IvsMonitorSelection.GetCurrentSelection. In some cases, the call to IvsMonitorSelection.GetCurrentSelection returns the following:
Interface not registered (Exception from HRESULT 0x80040155)
In other places in my code, this works without a problem but it consistently fails in one particular place. I don't understand how there can be a difference. Can anyone shed any light on why IvsMonitorSelection.GetCurrentSelection might return such an error?
Thanks, Notre
"Gary Chang[MSFT]" - 08 Nov 2005 05:58 GMT Hi Notre,
>My package is using IvsMonitorSelection.GetCurrentSelection. >In some cases, the call to IvsMonitorSelection.GetCurrentSelection [quoted text clipped - 4 lines] >In other places in my code, this works without a problem but it >consistently fails in one particular place. Based on your description, the problem is your package works well in some cases, but gets the "Interface not registered" error with the IvsMonitorSelection.GetCurrentSelection in a particular place, please let me know if I have misunderstood anything.
Would you please give us more detailed information about the specific scenario, from where you continuously get the "Interface not registered" error with the IvsMonitorSelection.GetCurrentSelection
Thanks!
Best regards,
Gary Chang Microsoft Community Support -------------------- Get Secure! ¡§C www.microsoft.com/security Register to Access MSDN Managed Newsgroups! http://support.microsoft.com/default.aspx?scid=/servicedesks/msdn/nospam.asp &SD=msdn
This posting is provided "AS IS" with no warranties, and confers no rights.
Notre Poubelle - 08 Nov 2005 20:56 GMT Hi Gary,
Yes, you understand the symptom.
I am writing my own package that hooks into another package's project system by means of IVsBuildStatusCallBack. In my package's implementation of IVsBuildStatusCallBack::BuildEnd, I attempt to use IvsMonitorSelection.GetCurrentSelection. This is when I often get the problem.
Trevor
"Gary Chang[MSFT]" - 11 Nov 2005 01:40 GMT Hi Trevor,
I have consulted this issue with our VSIP specialist, it appears this problem could happen only in native code. The interface should be registered. However IVsBuildStatusCallBack can be called on background thread, so make sure that the IVsMonitorSelection that you are using in there has been marshaled. You can either use the GIT or CoMarshalInterThreadInterfaceInStream/CoGetInterfaceAndReleaseStream APIs. Alternatively you can post a message back to the main thread that will do the needful.
Thanks!
Best regards,
Gary Chang Microsoft Community Support -------------------- Get Secure! ¡§C www.microsoft.com/security Register to Access MSDN Managed Newsgroups! http://support.microsoft.com/default.aspx?scid=/servicedesks/msdn/nospam.asp &SD=msdn
This posting is provided "AS IS" with no warranties, and confers no rights.
Notre Poubelle - 24 Nov 2005 18:15 GMT Hi Gary,
I'm writing all my code in C#, which of course is using the VS interop assemblies to talk to the underlying VS native code.
I'm not explicitly creating a background thread. However, this may be happening behind the scenes. My package is set to auto load in the NoSolution context. It then listens for OnAfterOpenProject and OnBeforeCloseProject messages by registering for IVsSolutionEvents (actually I borrow the SolutionListener class from the MPF project system to assist in this). I filter out the project types by the project guid property and for the appropriate project types I register my package with IVsBuildStatusCallBack for all the build configurations.
According to VSIP project creation architecture video at http://www.vsipdev.com/techinfo/, the configuration builder object is a separate COM object because it generally wants to live on a separate thread. This allows the build action to take place asynchronously to the rest of the stuff happening in the environment. As I've not created the project system myself, I can't guarantee this is what's happening, but it seems likely. It is inside my implementation of IVsBuildStatusCallBack that I'm trying to use IvsMonitorSelection.GetCurrentSelection. In light of your VSIP developer's comments, could this be a problem? Note that I'm using IvsMonitorSelection.GetCurrentSelection in other spots of my implementation of IVsBuildStatusCallBack and it's working just fine.
Thanks, Notre
"Gary Chang[MSFT]" - 25 Nov 2005 10:00 GMT Hi Notre,
>As I've not created the project system myself, I can't guarantee >this iswhat's happening, but it seems likely. It is inside my >implementation of IVsBuildStatusCallBack that I'm trying to use >IvsMonitorSelection.GetCurrentSelection. In light of your VSIP >developer's comments, could this be a problem? Since we are not clear about the project system your package hooked, we are unable to determine does this matter?
Have you tried to apply your package to other standard .NET project systems, will this problem occur?
Thanks!
Best regards,
Gary Chang Microsoft Community Support -------------------- Get Secure! ¡§C www.microsoft.com/security Register to Access MSDN Managed Newsgroups! http://support.microsoft.com/default.aspx?scid=/servicedesks/msdn/nospam.asp &SD=msdn
This posting is provided "AS IS" with no warranties, and confers no rights.
Notre Poubelle - 25 Nov 2005 17:04 GMT Hi Gary,
My package is hooked into the Report Server Project, which is part of the Business Intellegince suite, installed as part of SQL Server 2005.
I've not tried this with a different project system type.
Notre
"Gary Chang[MSFT]" - 29 Nov 2005 05:55 GMT Hi Notre,
I got some opinions from a guy who happens to know this problem in RS project:
IVsBuildStatusCallBack::BuildEnd is actually called on a worker thread. VSIP docs don't seem to explicitly demand that IVsBuildStatusCallBack events be fired on any thread in particular, and thread-bound subscribers --such as VSCORE UI --would be taken care of by COM if they place themselves into STA apartment.
Based on the error message, you implement your package in managed code, which means your component is neural, and will be called directly from the worker thread. That is not the end of the world by itself, however I think that IVsMonitorSelection --or IVsMultiItemSelect it returns - are only supposed to be used from the UI thread only, which explains why this works fine in any other context.
Things being the way they are now, you will need to marshal yourself back over to the UI thread (with Control.Invoke() or similar) and call IVsMultiItemSelect from there.
wish this helps!
Best regards,
Gary Chang Microsoft Community Support -------------------- Get Secure! ¡§C www.microsoft.com/security Register to Access MSDN Managed Newsgroups! http://support.microsoft.com/default.aspx?scid=/servicedesks/msdn/nospam.asp &SD=msdn
This posting is provided "AS IS" with no warranties, and confers no rights.
Notre Poubelle - 29 Nov 2005 19:12 GMT Hi Gary,
Thank you very much for this. I believe your RS expert is right; I put breakpoints in my code and observed the thread Id of the active thread is not the main, UI thread in the scenario where IvsMonitorSelection.GetCurrentSelection returns the error code. So, I would like to follow the suggestion of marshalling to the UI thread.
I know how to use InvokeRequired and Invoke in general, but I don't know how to get access to a WindowsForm control object, from which I can call these methods. In my case, I do not have any toolwindows or other UI that I'm creating. So, I think I need to use something provided by the environment. I know how to get at the solution explorer UIHiearchyWindow (and probably its parent toolwindow), but I don't think this is a WinForm control. Can you please provide some guidance on how to marshal back to the UI thread, in the context of being a package that doesn't create a toolwindow (or any other UI) based on WinForms?
Thanks, Notre
"Gary Chang[MSFT]" - 01 Dec 2005 05:30 GMT Hi Notre,
I consulted that expert again:
There are many ways of achieving this--basically you need to "marshal" yourself back to the main thread. You can use STA COM objects, post messages to yourself etc.
If you don't have any UI at all, you can do something like this--that is pretty ugly and is not worth the trouble if you don't depend on WinForms already.
In the code that is *known* to be executed on the main thread--for instance all package loads are (do make sure you are not running in batch command line mode) ?you can force-create an instance of a an invisible form. It can go something like this:
Form marshalingForm = new Form ( );
marshalingForm.Visible = false;
IntPtr handle = marshalingForm.Handle; ?Important! This will force form creation. You might get a warnign about unused variable here.
ISynchronizeInvoke invoker = marshalingForm;
You need to store "invoker" AND "handle" in statics or elsewhere.
On your other thread you can do invoker.Invoke()--the call will take place on main thread. Again, this is not the bets of designs, but it will work
Thanks!
Best regards,
Gary Chang Microsoft Community Support -------------------- Get Secure! ¡§C www.microsoft.com/security Register to Access MSDN Managed Newsgroups! http://support.microsoft.com/default.aspx?scid=/servicedesks/msdn/nospam.asp &SD=msdn
This posting is provided "AS IS" with no warranties, and confers no rights.
Notre Poubelle - 01 Dec 2005 23:13 GMT Hi Gary,
I tried the hack suggested by your expert and it does seem to work. Thank you very much for your help and for his help.
One question I have now is related to some errrors I'm seeing. I'm getting occassional errors of type System.Threading.ThreadAbortException when I tried to debug my code and attempt to execute the invoker.InvokeRequired property. I haven't seen this problem while not under the debugger, so it may not be a real error.
What's more concerning, is that I'm seeing the message that Visual Studio is busy, after I perform my build operation, which marshals to the main UI thread. If under the debugger, often this is followed by a 'DisconnectedContext was detected message'. An example detail of this message follows:
Message: Context 0x157fa8' is disconnected. Releasing the interfaces from the current context (context 0x158118).This may cause corruption or data loss. To avoid this problem, please ensure that all contexts/apartments stay alive until the applicationis completely done with the RuntimeCallableWrappers that represent COM components that liveinside them.
I've not seen this message before, I and assume it is somehow related to the fact that I'm trying to marshal to another thread. Any suggestions? Note that I'm not calling Dispose on the marshalling form that was created in my package class; could this have anything to do with it? (If so, when would I safely call dispose)?
Thanks, Notre
"Gary Chang[MSFT]" - 07 Dec 2005 02:56 GMT Hi Notre,
>I've not seen this message before, I and assume it is >somehow related to the fact that I'm trying to marshal >to another thread. Any suggestions? Note that I'm not >calling Dispose on the marshalling form that was created >in my package class; could this have anything to do with it? >(If so, when would I safely call dispose)? I am afraid I don't have idea about this problem, have you tried to call the Dispose method, does it work?
If this issue still matters, I think you can send a self-alone repro project(zipped) to us for research, if it is not inconvenience to you.
Thanks!
Best regards,
Gary Chang Microsoft Community Support -------------------- Get Secure! ¡§C www.microsoft.com/security Register to Access MSDN Managed Newsgroups! http://support.microsoft.com/default.aspx?scid=/servicedesks/msdn/nospam.asp &SD=msdn
This posting is provided "AS IS" with no warranties, and confers no rights.
Notre Poubelle - 08 Dec 2005 21:27 GMT Hi Gary,
Any idea where I might call the Dispose property?
Are there other ways of achieving this in managed code without using the hidden windows form? While this (mostly) works, it's not the cleanest approach so I would prefer to use something else anyway.
Notre
"Gary Chang[MSFT]" - 09 Dec 2005 08:14 GMT Hi,
>Note that I'm not calling Dispose on the marshalling form that was >created in my package class; could this have anything to do with it? I suggest you may call the Dispose in that marshalling form's Closing event-handler function.
>Are there other ways of achieving this in managed code without >using the hidden windows form? While this (mostly) works, it's >not the cleanest approach so I would prefer to use something >else anyway. I am afraid currently I don't get any other workarounds:(
Thanks for your understanding!
Best regards,
Gary Chang Microsoft Community Support -------------------- Get Secure! ¡§C www.microsoft.com/security Register to Access MSDN Managed Newsgroups! http://support.microsoft.com/default.aspx?scid=/servicedesks/msdn/nospam.asp &SD=msdn
This posting is provided "AS IS" with no warranties, and confers no rights.
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|