Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WinRT bug: System.InvalidOperationException:“Attempt to update previously set global instance.” #623

Closed
taooceros opened this issue Dec 8, 2020 · 15 comments
Assignees
Milestone

Comments

@taooceros
Copy link

taooceros commented Dec 8, 2020

Description

When calling new PackageManager(), this error throw. Only the first time calling the constructor throws the error.

Configuration

Using .Net 5 with TargetFramework net5.0-windows10.0.19041.0.
The windows OS version is 20H2 x64.

Regression?

Not sure, but .net core 3.1 with the Windows.SDK.Contract works well.

Other information

StackTrace

   at System.Runtime.InteropServices.ComWrappers.RegisterForTrackerSupport(ComWrappers instance)
   at WinRT.ComWrappersSupport.get_ComWrappers()
   at WinRT.ComWrappersSupport.TryRegisterObjectForInterface(Object obj, IntPtr thisPtr)
   at WinRT.ComWrappersSupport.RegisterObjectForInterface(Object obj, IntPtr thisPtr)
   at Windows.Management.Deployment.PackageManager..ctor()
   at Flow.Launcher.Plugin.Program.Programs.UWP.CurrentUserPackages() in D:\Document\Dotnet\Flow.Launcher\Plugins\Flow.Launcher.Plugin.Program\Programs\UWP.cs:line 200
   at Flow.Launcher.Plugin.Program.Programs.UWP.All() in D:\Document\Dotnet\Flow.Launcher\Plugins\Flow.Launcher.Plugin.Program\Programs\UWP.cs:line 156

Similar bug

#394

@angelazhangmsft
Copy link
Contributor

@taooceros What version of .NET5 SDK are you using? This seems to be fixed in the latest (.NET 5.0.100)

@taooceros
Copy link
Author

@taooceros What version of .NET5 SDK are you using? This seems to be fixed in the latest (.NET 5.0.100)

Weird, I do use the latest version 5.0.100.

@Scottj1s
Copy link
Member

Scottj1s commented Dec 9, 2020

@taooceros, this can also occur if there are multiple versions of winrt.runtime.dll loaded in process, each with their own static instance of registration state. Do you have a repro project?

@taooceros
Copy link
Author

taooceros commented Dec 10, 2020

@Scottj1s check out https://github.com/taooceros/Flow.Launcher
The usage of new PackageManager is on here.

https://github.com/taooceros/Flow.Launcher/blob/113def721c6c1de191257113005a4482eb76e8e8/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs#L201-L210

This error only appears when the first time calling the constructor after opening a new instance of application.

@Scottj1s Scottj1s added this to the Release 1.2.0 milestone Dec 11, 2020
@Scottj1s Scottj1s self-assigned this Dec 11, 2020
@Scottj1s
Copy link
Member

another possibility is multiple calls to InitializeComWrappers

@j0shuams
Copy link
Contributor

@taooceros I tried to get a local repro using PackageManger and the constructor did not throw the error for me. I tried using the same function in your link (FindPackagesForUser) and still no error thrown. I cloned Flow.Launcher and built it but am not sure how you run it / were hitting this error. Running the unit tests doesn't seem to do anything (could be a VS issue)

Tracing back through callers of the method you linked, it seems ReIndexing gets called several times and the line Main.IndexPrograms() is not "awaited". Perhaps this is causing confusion by loading multiple WinRT.Runtime?

If you try awaiting and don't get the error, great! For now, I'll see if I can get a repro by putting PackageManger down stream of an async call. If you would share how I can repro with my clone of Flow.Launcher I could investigate more there.

@Scottj1s
Copy link
Member

per discussion, will add a check in ComWrappers set accessor for overlapping sets, and ignore subsequent ones that try to set the DefaultComWrappers (which should be benign). Along with this, will move the InitializeComWrappers default check into the set accessor, which, along with the get accessor, will then reference a singleton DefaultComWrappers.Instance property without requiring additional locking. DefaultComWrappers will also need a private ctor to force accesses to the Instance singleton.

@j0shuams
Copy link
Contributor

Closing as this should be fixed by #675

@taooceros
Copy link
Author

@taooceros I tried to get a local repro using PackageManger and the constructor did not throw the error for me. I tried using the same function in your link (FindPackagesForUser) and still no error thrown. I cloned Flow.Launcher and built it but am not sure how you run it / were hitting this error. Running the unit tests doesn't seem to do anything (could be a VS issue)

Tracing back through callers of the method you linked, it seems ReIndexing gets called several times and the line Main.IndexPrograms() is not "awaited". Perhaps this is causing confusion by loading multiple WinRT.Runtime?

If you try awaiting and don't get the error, great! For now, I'll see if I can get a repro by putting PackageManger down stream of an async call. If you would share how I can repro with my clone of Flow.Launcher I could investigate more there.

Well actually when I received this error, it shouldn't due to multiple calls at the same time, because it only throws at the first time I trying to initialize the new instance. By catching the error and initialize again, everything is fine. I have added that to my dev branch, which means the error may be suppressed. @j0shuams if possible, please take a try by removing the try catch when initializing the new instance of the package manager to see whether you are going to reproduce the error.

I am not sure whether this may be caused by some special condition in my computer, but when I found the issue, it appears quite stably, although not sure for now.

I believe the fix shall work. Thank you so much for the fix!

@taooceros
Copy link
Author

Hi, I would like to ask how shall we get the latest fix? It is getting worse that before it only happens at the first time constructs the PackageManager, but now it happens every time.

@taooceros
Copy link
Author

I have taken another round of try. It is weird that if the new is called on application (wpf) mainthread, it will be fine. However, as what we are using it, it is called from a threadpool thread. Will that matter?

@taooceros
Copy link
Author

taooceros commented Feb 24, 2021

@taooceros, this can also occur if there are multiple versions of winrt.runtime.dll loaded in process, each with their own static instance of registration state. Do you have a repro project?

Sorry that I haven't understood you quote really well before, but I think this is quite possible because it is a sub project referenced by the main project, (the main project has to be net5.0-windows10.0.19041.0 to reference the sub project so it also contains a WinRT.dll the main project referenced also to net5.0-windows10.0.19041.0 because of ModernWPF)

@manodasanW
Copy link
Member

@taooceros You can get the changes by updating to the latest .NET SDK servicing update.

@taooceros
Copy link
Author

@taooceros You can get the changes by updating to the latest .NET SDK servicing update.

ok, thanks. I solve this by removing the extra winrt assembly loading. Thanks for all your help!

@jlaanstra
Copy link
Collaborator

I'm running into this when activating an in-proc com server written in .NET.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants