How to Host PowerShell 5 from WinUI 3 C# App

Viewed 287

Hoping to get some guidance around hosting PowerShell 5.1 within a C# WinUI 3 application targeting .NET 6. I've been trying numerous different NuGet packages and unfortunately, the only thing I've been able to get working will call PowerShell 7. In my case, I need to be able to call PowerShell 5.1...

Packages I've tried adding:

  • Microsoft.PowerShell.5.ReferenceAssemblies - Not compatible

    • Warning NU1701 Package 'Microsoft.PowerShell.5.ReferenceAssemblies 1.1.0' was restored using '.NETFramework,Version=v4.6.1, .NETFramework,Version=v4.6.2, .NETFramework,Version=v4.7, .NETFramework,Version=v4.7.1, .NETFramework,Version=v4.7.2, .NETFramework,Version=v4.8' instead of the project target framework 'net6.0-windows10.0.19041'. This package may not be fully compatible with your project.
  • Microsoft.PowerShell.SDK - Only available for use with PowerShell 7, not Windows PowerShell 5.1

  • PowerShellLibrary.Standard - I don't believe this is applicable for hosting PowerShell within an app

I can work around this a bit by just calling a new process:

var script = "C:\\scripts space\\MultiLineTestScript.ps1";
var process = new Process
{
     StartInfo = new ProcessStartInfo(@"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe", "-ExecutionPolicy Bypass -NoProfile -File \"" + script + "\"")
        {
            RedirectStandardOutput = true,
            CreateNoWindow = true
        }
 };
 process.Start();

This works, but with that said I'd rather use a supported SDK or reference assembly if possible. Particularly for easier implementation of runspaces and getting the PowerShell host to run on a separate thread without hanging the UI.

I've found this: https://devblogs.microsoft.com/powershell/depending-on-the-right-powershell-nuget-package-in-your-net-project/

Is it not supported/possible to host Windows PowerShell 5.1 within a WinUI 3 .net Core app? Any help would be appreciated, I am generally a PowerShell user not a C# dev but I am stumbling my way through.

1 Answers

tl;dr

  • Hosting the Windows PowerShell SDK in a .NET (Core) application is not possible, as you have since confirmed via Twitter.

  • Calling PowerShell in a child process via its CLI, powershell.exe, may indeed be your only option.


To start with a recap:

Since Windows PowerShell is based on the legacy, Windows-only .NET Framework (as opposed to its successor, the cross-platform .NET Core / .NET 5+ framework), so is the NuGet SDK package that allows hosting Windows PowerShell in an application, Microsoft.PowerShell.5.1.ReferenceAssemblies.

Your project targets .NET 6.0 (net60), which is why you're seeing a warning regarding the mismatch in target frameworks when you build your project.


While the fact that this is only a warning, not an error, suggests that this mismatched combination may situationally work nonetheless, this is not the case for trying to host Windows PowerShell in a .NET (Core) 6.0 application: an exception is thrown on trying to instantiate the PowerShell class: System.InvalidProgramException: Common Language Runtime detected an invalid program.

Using the Microsoft.Windows.Compatibility package (discussed in this article) doesn't help.

Therefore, calling Windows PowerShell via its CLI, powershell.exe, as a child process is indeed your best option.

Apart from being slower and more resource-intensive, an additional drawback is that only text output can be received.

Related