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

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

Closed
5 tasks done
wrharper opened this issue May 13, 2024 · 41 comments
Closed
5 tasks done

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

wrharper opened this issue May 13, 2024 · 41 comments
Labels
Issue-Question ideally support can be provided via other mechanisms, but sometimes folks do open an issue to get a Resolution-Answered The question is answered.

Comments

@wrharper
Copy link

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

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 wrharper added the Needs-Triage The issue is new and needs to be triaged by a work group. label May 13, 2024
@wrharper
Copy link
Author

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
Copy link

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
Copy link
Author

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

@rhubarb-geek-nz
Copy link

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
Copy link
Collaborator

SeeminglyScience commented May 14, 2024

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.

@SeeminglyScience SeeminglyScience added Issue-Question ideally support can be provided via other mechanisms, but sometimes folks do open an issue to get a Resolution-Answered The question is answered. and removed Needs-Triage The issue is new and needs to be triaged by a work group. labels May 14, 2024
@wrharper
Copy link
Author

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
Copy link
Author

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
Copy link

rhubarb-geek-nz commented May 15, 2024

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

@rhubarb-geek-nz
Copy link

rhubarb-geek-nz commented May 15, 2024

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
Copy link
Author

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
Copy link

rhubarb-geek-nz commented May 15, 2024

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

  • Only load the classes that don't conflict into the PowerShell process
  • If you do have classes that conflict then load them in a seperate AssemblyLoadContext
  • share the same runtime from c:\Program Files\dotnet\shared by using the dotnet powershell tool
  • If all that fails, simply run the WinUI3 code in a different process

I don't see any changes required from either .NET or PowerShell, the same rules apply to everyone.

@SeeminglyScience
Copy link
Collaborator

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
Copy link
Author

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
Copy link

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
Copy link
Author

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
Copy link

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
Copy link

HotCakeX commented May 16, 2024

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
Copy link

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
Copy link
Collaborator

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
Copy link
Author

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
Copy link

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
Copy link
Author

wrharper commented May 17, 2024

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
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
Copy link
Author

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
Copy link

rhubarb-geek-nz commented May 17, 2024

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
Copy link
Author

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
Copy link

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
Copy link
Author

wrharper commented May 17, 2024

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
Copy link

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
Copy link
Author

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
Copy link

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
Copy link
Author

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
Copy link
Author

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.

Copy link
Contributor

microsoft-github-policy-service bot commented May 17, 2024

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

🔗 https://aka.ms/PSRepoFeedback

@rhubarb-geek-nz
Copy link

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
Copy link
Author

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
Copy link

rhubarb-geek-nz commented May 17, 2024

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
Copy link

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
Copy link

rhubarb-geek-nz commented May 17, 2024

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
Copy link

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
Copy link

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
Copy link
Author

Yeah, 7.4.2 should be what majority is using.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Issue-Question ideally support can be provided via other mechanisms, but sometimes folks do open an issue to get a Resolution-Answered The question is answered.
Projects
None yet
Development

No branches or pull requests

4 participants