Project-system: ProjectItem.FileCodeModel throws TargetInvocationException

Created on 13 Dec 2016  路  11Comments  路  Source: dotnet/project-system

Hello,

When I try to read the FileCodeModel property from a ProjectItem, a TargetInvocationException is being thrown:

[16004] System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.InvalidCastException: Unable to cast COM object of type 'System.__ComObject' to interface type 'IMutableComWrapperFixed'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{3F2A41D1-125C-49C1-9773-1E0ECD311F00}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)). 
[16004]    at Microsoft.VisualStudio.PlatformUI.ComWrapperFactory.CreateAggregatedObject(Object obj) 
[16004]    at Microsoft.VisualStudio.LanguageServices.Implementation.CodeModel.Interop.ApartmentSensitiveComObject.GetComHandle[THandle,TObject]() 
[16004]    at Microsoft.VisualStudio.LanguageServices.Implementation.CodeModel.CodeModelProjectCache.GetOrCreateFileCodeModel(String filePath, Object parent) 
[16004]    at Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem.CPS.CPSProjectCodeModel.GetFileCodeModel(ProjectItem item) 
[16004]    at Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem.CPS.CPSProject.GetFileCodeModel(ProjectItem item) 
[16004]    at Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem.CPS.CPSCodeModelFactory.GetFileCodeModel(IWorkspaceProjectContext context, ProjectItem item) 
[16004]    at Microsoft.VisualStudio.ProjectSystem.VS.LanguageServices.ProjectContextCodeModelProvider.GetFileCodeModel(ProjectItem fileItem) 
[16004]    at Microsoft.VisualStudio.ProjectSystem.VS.Implementation.Package.Automation.OAProjectItem.get_FileCodeModel() 

Any idea what the issue is?

Thanks!

Bug

All 11 comments

Hmm, this is nothing you are doing. This is one of those "not sure exactly how this is possible, kinds of things". Is this pretty consistent? Looking at stack - this should occur for normal .NET Framework projects, does it?

@pharring have you seen this before in the past? How would this even occur? Broken IID_IComWrapper registration pointing to the wrong object?

@jviau, do you think anything around the changes you made might have caused this?

@jcansdale Is this this from today's build?

This was with the original Visual Studio 2017 RC release and ".NET Core and Docker (Preview)". It appeared to be consistent and only with .NET Core projects.

I've just tried installing the recent RC update to see if that makes a difference. Unfortunately .NET Core projects no longer seem to work (1.0.1 or 1.1.0).

netcore

Is there anything you would like me to try?

I am not sure if this is a CPS issue, but I have seen this in CPS before with the COM aggregation work. I think it is thread affinity. ComWrapperFactory.CreateAggregatedObject needs to be on the main thread.

Yeah that's exactly it. Jamie, I'm guessing you are doing this on a background thread? In the old project system due to COM marshalling would have automatically marshalled back to the UI thread.

I'm pushing this FileModel retrieval onto the UI thread - which Rolsyn is expecting anyway.

Thanks folks. Yes, this is on a background thread.

This code was written in the bad old days, way before async. Is there an easy way I could marshal onto the UI thread for this call? I could probably execute it as a separate command, but this would be pretty convoluted.

To add little extra complexity, what if the thread was running in a separate app domain? When this code is deployed it won't be, but for testing it's very useful being able to run in a separate domain. Do I have a hope of getting this working? 馃槃

If the underlying object that is being wrapper can be ran on any thread, then I suggest using WrapperPolicy.CreateFreeThreadedAggregatedObject. The aggregation still needs to be on the main thread, but usage of the returned object can be any thread.

Thanks for the tip! Does this need to be done on a per object basis? Or would wrapping DTE, wrap the objects returned recursively? (I realize I'm probably being a bit optimistic 馃槈)

@jviau Jamie is a consumer of these objects, not creating them, he shouldn't be using WrapperPolicy.

Jamie, as a workaround until this issue is fixed, marshal to the UI thread before access the FileCodeModel , here's an example:

``` C#
ThreadHelper.JoinableTaskFactory.RunAsync(VsTaskRunContext.UIThreadNormalPriority, async () =>
{
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();

// Use FileCodeModel

});
```

@davkean Thank you very much for the workaround and the fix. I look forward to trying the new version.

Happy holidays! 馃槃

No problems, happy holidays back to you.

If you run into any sort of weirdness or behavior difference from the old project system, feel free to file a bug.

Was this page helpful?
0 / 5 - 0 ratings