-
Notifications
You must be signed in to change notification settings - Fork 7.1k
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
.Net 8 in PowerShell 7 System.Private.CoreLib fails to register. #23792
Comments
Your System.Private.CoreLib.dll may be conflicting with C:\Program Files\PowerShell\7\System.Private.CoreLib.dll check the version with
You may need to load the WinUI3 runtime into another AssemblyLoadContext. |
Try and see, you will see it won't work either way. |
What version of System.Private.CoreLib.dll do you want to use?
My understanding is that (a) the names must be unique in an assembly load context When I created a WinUI3 project from the template I ended up with a net6.0 version which I expect to have many conflicts with net8.0. Is your project in GitHub? |
The exception is thrown from a class in corelib, which is already loaded. It's a core part of the runtime. The issue is that the COM component it's trying to load cannot be found. Loading WinUI 3 is a bit more complicated than that. In fact only yesterday I've I seen the first example of someone successfully loading it in this SO answer. |
These are workarounds and not solutions to the main point. If you install the same nugets I did, there should be no difference. |
Yes, exactly. How can we fix it so the runtime is more compatible. This would open a lot more for PowerShell if that got fixed. |
There are a number of reasons why this does not and should not work
If you are trying to load the Winui3 class libraries in the PowerShell process then only load those that are not already part of PowerShell. A build of a WinUI3 app includes the entire .NET runtime, so does PowerShell. If you want to use PowerShell process then use PowerShell's version of the .NET runtime. If you want to load the PowerShell SDK into a Winui3 app then that is a different matter and you will use the Winui3 app's .NET runtime. An alternative approach is to use the dotnet powershell tool, this does not contain the .NET runtime,, this uses the installed SDK version of the .NET runtime from |
I suggest do
to get the actual deliverable app. Then you can see the entire .NET runtime duplicated. Ideally the end result of this exercise should be a PowerShell module with the x86, x64 and arm64 binaries all packaged in a single module with a few cmdlets to create key instances. This should only contain the WinUI3 assemblies, not the .NET runtime as PowerShell should provide that. |
Right, well I tried. That is exactly what needs to change. There should not be conflicts like this. |
What needs to be changed? There is only one version of each named assembly permitted in each assembly load context because otherwise the dll import/export bindings would fail because they would not know which library they should be resolved against at runtime .NET already has a solution to this which is running different versions in different AssemblyLoadContexts, but you have to set that up. System.Private.CoreLib. is one of the libraries that is so fundamental to operation that it can't be replaced, it is effectively the core of .NET runtime. When in a .NET process all assemblies refer to that single assembly. So you have a few options
I don't see any changes required from either .NET or PowerShell, the same rules apply to everyone. |
To be clear the issue is not about loading When it comes to easier loading of WinUI3 in PowerShell, having briefly looked into it I can say there isn't much that PowerShell specifically can do easily. I'd recommend passing that feedback to the team working on WinUI via the feedback hub. |
Why can't simple version checks be done and then use that version? Why are you locked into one? Why can't it just automatically use the correct version or at least ask? Bad design. |
.NET has implemented a system which is a compromise, but it is a simple, practical and predictable solution to DLL Hell. PowerShell uses .NET so abides by those rules. So does WinUI3. |
It is reasons like this I recommend everyone uses c# and never touch PowerShell. You are just using it anyway in this case. It is the same thing but worse. The only benefit is company policies that allow PowerShell but not exes. That is the only thing it has going for it which is funny because of the ability to execute C# anyway. |
I suggest you take a step back and ask what you (and everyone else) are trying to achieve. PowerShell has plenty of uses as a cross platform scripting system for configuration, administration, build tasks, etc. However I would suggest that building GUIs is definitely not one of those uses. For starters, it is a console app. So if you want to build a GUI you now have this pointless black rectangle. Unless you are on Windows and using WinForms, you don't have the GUI toolkit and you have to carry that around along with all its conflicts. PowerShell is designed to load generally small components (cmdlets) to perform tasks in a shared environment where everyone treads lightly to avoid conflicting. Loading large monolithic applications into the PowerShell process is not what it was designed to do, but nothing prevents you doing it as long as you play by the rules. If you do manage to load a GUI toolkit into a PowerShell process to be driven by scripting, it will perform like a dog. PowerShell on Windows insists on running absolutely everything past the anti-malware scanner including every method call from your script to the GUI toolkit. So yes I completely agree, don't try and build GUI applications with PowerShell. Just like I recommend don't build a website using PowerShell, yes you can do it but there are far better technologies to do that, eg ASP.NET. That said, there is nothing stopping you using the PowerShell SDK within your GUI application to run various tasks or menu operations within the app using scripts allowing you to extend your app from within. |
The fact that it runs everything past the Anti-Malware scanner is amazing! Security is more important than productivity, that's something Microsoft also realizes now. Building applications using PowerShell means the end-user can trust your code easier without the need to rebuild your application from the source, which requires setting up dev environments etc. and a lot of people don't do that. Building applications with PowerShell also won't require you to necessarily buy code signing certificate to run it in secure environments where random unsigned stuff from the Internet isn't allowed to run, at least not elevated, and that's because of the fact you mentioned, it's uncompiled so AM has eyes on it and the code that is being run. So I think PowerShell should be used for GUI applications too, it can be used with WinForms and WPF, now this new WinUI3 is a bit rough around the edges with PowerShell support but fortunately the great community never disappoints. (look at the answer here) |
Not really, it is security theatre. Put it in a compiled Cmdlet and it is not scanned and use reflection to bypass the method invocation scanning. |
I guess I'm not explaining this properly, but the error you're getting is about a COM component that is failing to load more or less due to WinUI expecting to be in a store app. The source tells you what assembly threw the error, loading a different copy of |
Everything else everyone is trying to do is possible in C#. There is nothing it can do that C# can't, but not visa versa. That was my point. |
Sure it uses .NET as its implementation and can only run in environment where .NET is available, but what it can do is provide a scripting environment for non-technical users to write simple scripts to automate activities. Given that is it's purpose I don't see any problem with that.
And if you have a .NET program, you can use the PowerShell SDK to implement the same scripting in your application. Again there is nothing wrong with that. It's just a tool. |
Someone else gave a 2nd answer that is better than the first in https://stackoverflow.com/questions/78468949/how-to-create-winui3-gui-in-powershell/78472867 The only confusing part about this is the error in PowerShell is actually misleading. As you can see from the answers, they do not ever mention the Private Lib.
I would like to know the exact dll and how this is being bypassed. That is interesting.
|
To be more specific, the 1st answer bypasses the warning with /nowarn:CS1701 and keeps it as a c# compiler but the 2nd one doesn't even need to do that? So what specifically is making this possible? |
If you look at a standard WinUI3 project you can see it is targeted at net6.0, in PowerShell terms that would be running on PowerShell 7.2.*
As the comment says
The first sample that worked had the embedded C# code. It looks like the warning that is disabled is because it is not being compiled with net6.0. The second sample was written all in PowerShell so there was no C# compilation step in the script. |
right, the 2nd answer is the strange one. if you use PowerShell 7.4.2 it is .NET 8. So how is it loading without issue in that case? Shouldn't they end up getting the same error? |
I expect it is because the warning is just a compilation warning. The binding in the dlls will say "I need at least version X" and the currently running one may satisfy that. |
the stacktrace is a little misleading in this case then because loading the PrivateLib was the wrong direction entirely. How would you connect this and know the answer to an issue like this? That is what I'm getting at. How can you know and figure out something like this without it already being told to you? Usually, stacktraces are the best way to find out exactly how to fix an issue, but not in this case. In fact, this is the first time i've ever seen a stacktrace be the wrong direction. |
If you had tried the original using PowerShell 7.2 then you may not have come across the CoreLib problem because the currently executing one satisfied the dependencies. I think you may have had quicker success using PowerShell based on net6.0 and a WinUI3 SDK expecting net6.0. I am sure you would still have other problems, but perhaps not that one. |
I agree, that was a suggestion I had at the very beginning, but this was a requirement. |
However you may have got something going and determined the minimal set of dlls that need to be loaded into the process and seen you don't need to duplicate the entire dotnet runtime. Then you could have tried in 7.3 and then 7.4. |
Oh, still go back and use it as a troubleshooting step essentially. I see |
Well, we have an answer now that is valid. 2 technically. The main thing is everything always seems to be workarounds to the direct issues at hand instead of just making things work. I see this a ton in .NET. At this point, I guess we can close it as a workaround solution. It's still unclear on the 2nd answer what specifically that workaround is though. |
📣 Hey @wrharper, how did we do? We would love to hear your feedback with the link below! 🗣️ 🔗 https://aka.ms/PSRepoFeedback |
Absolutely, when I write PowerShell scripts and modules I try and get them running on all versions of PowerShell and all CPU architectures. It is most common to target code for netstandard2.0 when building PowerShell code because it will run on PowerShell Desktop and PowerShell Core and is not dependent on the specific version of the runtime. There may be specific scenarios where it can only run on core, then I use net6.0 because that lets you use the AssemblyLoadContext. |
This is going a little off topic, but this is the main issue I fear with new .NET versions right here... they try to "over" simplify and in turn it actually makes things worse. |
One of the advantages of building a standalone WinUI3 app is you are in complete control of the runtime, it is packaged in the msix as a dependency. However with PowerShell you don't get to choose the version of PowerShell, that is the user's choice. Given that PowerShell 7 is not part of windows, users may not have it at all, not know that it exists, or have a very old one. So it depends on who your target audience is which versions of PowerShell you choose to support. |
There, don't need to be overdramatic. Create a PS1 file that checks the PowerShell version, installs latest version or update it using Winget, then calls pwsh.exe and runs the script/module/cmdlet. There is always a way and this is very simple. |
You may not have admin rights, you may be on a locked down PC. For the majority of Windows users they would never even look at a solution if it required some kind of command prompt. So it all depends on your audience. For the majority of users a free app from the Windows App Store is the simplest solution, exactly what WinUI3 is designed to support. |
You can use AdvancedInstaller, they are Microsoft partner, create MSI file for your PowerShell module, assign nice icon to it, show it on desktop, in the installed apps section of settings etc. |
That is good, at the end of the day it is about getting a working solution to your audience. |
Yeah, 7.4.2 should be what majority is using. |
Prerequisites
Steps to reproduce
Create a project in visual studio for a WinUI 3 application and do a build to get the .dlls in the Bin folder.
Load:
cd "go to your project bin folder"
add-type -Path Microsoft.Windows.SDK.NET.dll
add-type -Path WinRT.Runtime.dll
add-type -Path Microsoft.WinUI.dll
New-Object -TypeName Microsoft.UI.Xaml.Window
Root cause of stack appears to be:
Message : Class not registered (0x80040154 (REGDB_E_CLASSNOTREG))
Source : System.Private.CoreLib
When trying to load it:
add-type -Path System.Private.CoreLib.dll
Add-Type: Could not load file or assembly 'System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e'.
Exception :
Type : System.IO.FileLoadException
Message : Could not load file or assembly 'System.Private.CoreLib, Version=8.0.0.0, Culture=neutral,
PublicKeyToken=7cec85d7bea7798e'.
TargetSite :
Name : LoadFromAssemblyPath
DeclaringType : [System.Runtime.Loader.AssemblyLoadContext]
MemberType : Method
Module : System.Private.CoreLib.dll
Source : System.Private.CoreLib
HResult : -2146232799
StackTrace :
at System.Runtime.Loader.AssemblyLoadContext.LoadFromAssemblyPath(String assemblyPath)
at System.Reflection.Assembly.LoadFrom(String assemblyFile)
at Microsoft.PowerShell.Commands.AddTypeCommand.LoadAssemblies(IEnumerable`1 assemblies)
at System.Management.Automation.CommandProcessorBase.Complete()
CategoryInfo : NotSpecified: (:) [Add-Type], FileLoadException
FullyQualifiedErrorId : System.IO.FileLoadException,Microsoft.PowerShell.Commands.AddTypeCommand
InvocationInfo :
MyCommand : Add-Type
ScriptLineNumber : 1
OffsetInLine : 1
HistoryId : 15
Line : add-type -Path System.Private.CoreLib.dll
Statement : add-type -Path System.Private.CoreLib.dll
PositionMessage : At line:1 char:1
+ add-type -Path System.Private.CoreLib.dll
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
InvocationName : add-type
CommandOrigin : Internal
ScriptStackTrace : at , : line 1
Expected behavior
Just being able to load a Xaml Window.
Actual behavior
Exception calling ".ctor" with "0" argument(s): "The type initializer for '_IWindowFactory' threw an exception."
Error details
Environment data
Visuals
No response
The text was updated successfully, but these errors were encountered: