PowerShell / PowerShell

PowerShell for every system!
https://microsoft.com/PowerShell
MIT License
43.66k stars 7.08k forks source link

.Net 8 in PowerShell 7 System.Private.CoreLib fails to register. #23792

Closed wrharper closed 2 weeks ago

wrharper commented 2 weeks ago

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

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

Exception             :
    Type           : System.Management.Automation.MethodInvocationException
    ErrorRecord    :
        Exception             :
            Type    : System.Management.Automation.ParentContainsErrorRecordException
            Message : Exception calling ".ctor" with "0" argument(s): "The type initializer for '_IWindowFactory'
threw an exception."
            HResult : -2146233087
        CategoryInfo          : NotSpecified: (:) [], ParentContainsErrorRecordException
        FullyQualifiedErrorId : DotNetconstructorTargetInvocation
    TargetSite     :
        Name          : AuxiliaryConstructorInvoke
        DeclaringType : [System.Management.Automation.DotNetAdapter]
        MemberType    : Method
        Module        : System.Management.Automation.dll
    Message        : Exception calling ".ctor" with "0" argument(s): "The type initializer for '_IWindowFactory' threw
an exception."
    InnerException :
        Type           : System.TypeInitializationException
        TypeName       : _IWindowFactory
        TargetSite     :
            Name          : get_Instance
            DeclaringType : [Microsoft.UI.Xaml.Window+_IWindowFactory]
            MemberType    : Method
            Module        : Microsoft.WinUI.dll
        Message        : The type initializer for '_IWindowFactory' threw an exception.
        InnerException :
            Type           : System.TypeInitializationException
            TypeName       : WinRT.ActivationFactory`1
            TargetSite     :
                Name          : As
                DeclaringType : [WinRT.ActivationFactory`1[T]]
                MemberType    : Method
                Module        : Microsoft.WinUI.dll
            Message        : The type initializer for 'WinRT.ActivationFactory`1' threw an exception.
            InnerException :
                Type       : System.Runtime.InteropServices.COMException
                ErrorCode  : -2147221164
                TargetSite :
                    Name          : ThrowExceptionForHR
                    DeclaringType : [System.Runtime.InteropServices.Marshal]
                    MemberType    : Method
                    Module        : System.Private.CoreLib.dll
                Message    : Class not registered (0x80040154 (REGDB_E_CLASSNOTREG))
                Source     : System.Private.CoreLib
                HResult    : -2147221164
                StackTrace :
   at System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(Int32 errorCode)
   at WinRT.BaseActivationFactory..ctor(String typeNamespace, String typeFullName)
   at WinRT.ActivationFactory`1..ctor()
   at WinRT.ActivationFactory`1..cctor()
            Source         : Microsoft.WinUI
            HResult        : -2146233036
            StackTrace     :
   at WinRT.ActivationFactory`1.As(Guid iid)
   at Microsoft.UI.Xaml.Window._IWindowFactory..ctor()
   at Microsoft.UI.Xaml.Window._IWindowFactory..cctor()
        Source         : Microsoft.WinUI
        HResult        : -2146233036
        StackTrace     :
   at Microsoft.UI.Xaml.Window._IWindowFactory.get_Instance()
   at Microsoft.UI.Xaml.Window..ctor()
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
   at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
    Source         : System.Management.Automation
    HResult        : -2146233087
    StackTrace     :
   at System.Management.Automation.DotNetAdapter.AuxiliaryConstructorInvoke(MethodInformation methodInformation,
Object[] arguments, Object[] originalArguments)
   at System.Management.Automation.DotNetAdapter.ConstructorInvokeDotNet(Type type, ConstructorInfo[] constructors,
Object[] arguments)
   at Microsoft.PowerShell.Commands.NewObjectCommand.CallConstructor(Type type, ConstructorInfo[] constructors,
Object[] args)
CategoryInfo          : InvalidOperation: (:) [New-Object], MethodInvocationException
FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand
InvocationInfo        :
    MyCommand        : New-Object
    ScriptLineNumber : 1
    OffsetInLine     : 1
    HistoryId        : 11
    Line             : New-Object -TypeName Microsoft.UI.Xaml.Window
    Statement        : New-Object -TypeName Microsoft.UI.Xaml.Window
    PositionMessage  : At line:1 char:1
                       + New-Object -TypeName Microsoft.UI.Xaml.Window
                       + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    InvocationName   : New-Object
    CommandOrigin    : Internal
ScriptStackTrace      : at <ScriptBlock>, <No file>: line 1

Environment data

$PSVersionTable
Name                           Value
----                           -----
PSVersion                      7.4.2
PSEdition                      Core
GitCommitId                    7.4.2
OS                             Microsoft Windows 10.0.22631
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

[System.Runtime.InteropServices.RuntimeInformation]::FrameworkDescription
.NET 8.0.4

Visuals

No response

wrharper commented 2 weeks ago

Also have the latest version of packages to ensure the latest dlls are used for Microsoft.Windows.SDK.BuildTools & Microsoft.WindowsAppSDK image

rhubarb-geek-nz commented 2 weeks ago

Your System.Private.CoreLib.dll may be conflicting with C:\Program Files\PowerShell\7\System.Private.CoreLib.dll

check the version with

(Get-Item 'C:\Program Files\PowerShell\7\System.Private.CoreLib.dll').VersionInfo

You may need to load the WinUI3 runtime into another AssemblyLoadContext.

wrharper commented 2 weeks ago

Try and see, you will see it won't work either way.

rhubarb-geek-nz commented 2 weeks ago

What version of System.Private.CoreLib.dll do you want to use?

Path                                                     FileVersion
----                                                     -----------
C:\Program Files\PowerShell\7\pwsh.exe                   7.4.2.500
C:\Program Files\PowerShell\7\System.Private.CoreLib.dll 8.0.424.16909

My understanding is that

(a) the names must be unique in an assembly load context (b) System.Private.CoreLib is right at the bottom of the stack, it is very primitive, you can't replace the one that is already running

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?

SeeminglyScience commented 2 weeks ago

Root cause of stack appears to be: Message : Class not registered (0x80040154 (REGDB_E_CLASSNOTREG)) Source : System.Private.CoreLib

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.

wrharper commented 2 weeks ago

These are workarounds and not solutions to the main point. The stackexchange uses the C# compiler. It isn't even PowerShell at that point. As you can see in the error it is .net 8 Add-Type: Could not load file or assembly 'System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e'.

If you install the same nugets I did, there should be no difference.

wrharper commented 2 weeks ago

Root cause of stack appears to be: Message : Class not registered (0x80040154 (REGDB_E_CLASSNOTREG)) Source : System.Private.CoreLib

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.

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.

rhubarb-geek-nz commented 2 weeks ago

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 C:\Program Files\dotnet\shared

rhubarb-geek-nz commented 2 weeks ago

Create a project in visual studio for a WinUI 3 application and do a build to get the .dlls in the Bin folder.

I suggest do

dotnet publish --configuration Release 

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.

wrharper commented 2 weeks ago

There are a number of reasons why this does not and should not work

  • PowerShell 7.4.2 uses System.Private.CoreLib.dll 8.0.424.16909
  • You can't have two assemblies with the same name in the same assembly load context
  • System.Private.CoreLib is already loaded so you can't load another with the same name
  • You are trying to replace a more recent System.Private.CoreLib with one that has an earlier version number

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 C:\Program Files\dotnet\shared

Right, well I tried. That is exactly what needs to change. There should not be conflicts like this.

rhubarb-geek-nz commented 2 weeks ago

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.

SeeminglyScience commented 2 weeks ago

To be clear the issue is not about loading System.Private.CoreLib. The error posted is saying that the exception is thrown from an API in the already loaded assembly. Most exceptions are thrown from this assembly, it's mostly irrelevant to the problem.

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.

wrharper commented 2 weeks ago

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.

rhubarb-geek-nz commented 2 weeks ago

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.

wrharper commented 2 weeks ago

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.

rhubarb-geek-nz commented 2 weeks ago

It is reasons like this I recommend everyone uses c# and never touch PowerShell.

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.

HotCakeX commented 2 weeks ago

It is reasons like this I recommend everyone uses c# and never touch PowerShell.

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)

rhubarb-geek-nz commented 2 weeks ago

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.

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.

SeeminglyScience commented 2 weeks ago

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.

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 System.Private.CoreLib would do nothing to help your issue. That extra copy of the library would simply also throw.

wrharper commented 2 weeks ago

It is reasons like this I recommend everyone uses c# and never touch PowerShell.

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.

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.

rhubarb-geek-nz commented 2 weeks ago

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.

$ dpkg -l powershell
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name           Version      Architecture Description
+++-==============-============-============-==================================================================
ii  powershell     7.4.2-1.deb  armhf        PowerShell is an automation and configuration management platform.

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.

wrharper commented 2 weeks ago

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 This is now possible to use in PowerShell code 100%. The issue with the first answer is there was no cross reference for making objects like the 2nd answer. This is a way better answer and good enough to make things possible.

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.

Add-Type -Path ".\WinRT.Runtime.dll"
Add-Type -Path ".\Microsoft.Windows.SDK.NET.dll"
Add-Type -Path ".\Microsoft.WindowsAppRuntime.Bootstrap.Net.dll"
Add-Type -Path ".\Microsoft.InteractiveExperiences.Projection.dll"
Add-Type -Path ".\Microsoft.WinUI.dll"

I would like to know the exact dll and how this is being bypassed. That is interesting.

Stack Overflow
How to create WinUI3 GUI in PowerShell?
The Goal Creating and rendering a simple WinUI3 GUI in PowerShell 7.5 which is based on .NET 9. Nothing complicated, just a window and a button in it, such as this XAML <?xml version="1.0&q...
wrharper commented 2 weeks ago

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?

rhubarb-geek-nz commented 2 weeks ago

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.*

    <OutputType>WinExe</OutputType>
    <TargetFramework>net6.0-windows10.0.19041.0</TargetFramework>
    <TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
    <RootNamespace>App1</RootNamespace>
    <ApplicationManifest>app.manifest</ApplicationManifest>
    <Platforms>x86;x64;ARM64</Platforms>
    <RuntimeIdentifiers>win10-x86;win10-x64;win10-arm64</RuntimeIdentifiers>

As the comment says

The content of the latest Microsoft.WindowsAppSDK package nuget, only the lib\net6.0-windows10.0.18362.0 directory (as of today, it's not targeting .NET 8),

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.

wrharper commented 2 weeks ago

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.*

    <OutputType>WinExe</OutputType>
    <TargetFramework>net6.0-windows10.0.19041.0</TargetFramework>
    <TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
    <RootNamespace>App1</RootNamespace>
    <ApplicationManifest>app.manifest</ApplicationManifest>
    <Platforms>x86;x64;ARM64</Platforms>
    <RuntimeIdentifiers>win10-x86;win10-x64;win10-arm64</RuntimeIdentifiers>

As the comment says

The content of the latest Microsoft.WindowsAppSDK package nuget, only the lib\net6.0-windows10.0.18362.0 directory (as of today, it's not targeting .NET 8),

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?

rhubarb-geek-nz commented 2 weeks ago

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.

wrharper commented 2 weeks ago

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.

rhubarb-geek-nz commented 2 weeks ago

the stacktrace is a little misleading in this case then because loading the PrivateLib was the wrong direction entirely.

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.

wrharper commented 2 weeks ago

the stacktrace is a little misleading in this case then because loading the PrivateLib was the wrong direction entirely.

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.

rhubarb-geek-nz commented 2 weeks ago

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.

wrharper commented 2 weeks ago

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

wrharper commented 2 weeks ago

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.

microsoft-github-policy-service[bot] commented 2 weeks ago

📣 Hey @wrharper, how did we do? We would love to hear your feedback with the link below! 🗣️

🔗 https://aka.ms/PSRepoFeedback

Microsoft Forms
rhubarb-geek-nz commented 2 weeks ago

Oh, still go back and use it as a troubleshooting step essentially. I see

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.

wrharper commented 2 weeks ago

Oh, still go back and use it as a troubleshooting step essentially. I see

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.

rhubarb-geek-nz commented 2 weeks ago

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. At least the System.Windows.Forms dlls are already installed with PowerShell core.

HotCakeX commented 2 weeks ago

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. At least the System.Windows.Forms dlls are already installed with PowerShell core.

Winget install Microsoft.PowerShell

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.

rhubarb-geek-nz commented 2 weeks ago

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.

HotCakeX commented 2 weeks ago

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. Users will have nice experience installing and using it. I've done it before for totally non-technical users.

rhubarb-geek-nz commented 2 weeks ago

Users will have nice experience installing and using it. I've done it before for totally non-technical users.

That is good, at the end of the day it is about getting a working solution to your audience.

wrharper commented 2 weeks ago

Yeah, 7.4.2 should be what majority is using.