如何从WinUI 3 C#应用程序托管PowerShell 5

kcugc4gi  于 2022-11-10  发布在  Shell
关注(0)|答案(2)|浏览(183)

我希望得到一些关于在面向.NET 6的C#WinUI3应用程序中托管*PowerShell5.1**的指导。我已经尝试了许多不同的NuGet包,不幸的是,我唯一能够运行的就是PowerShell7。在我的情况下,我需要能够调用PowerShell5.1...
我尝试添加的包:

  • Microsoft.PowerShell.5.ReferenceAssembly-不兼容
  • 警告NU1701包‘Microsoft.PowerShell.5.ReferenceAssembly 1.1.0’已使用‘.NETFramework,Version=v4.6.1,.NETFrame,Version=v4.6.2,.NETFrame,Version=v4.7,.NETFrame,Version=v4.7.1,.NETFrame,Version=v4.7.2,.NETFrame,Version=v4.8’还原,而不是使用项目目标框架‘net6.0-windows10.0.19041’。此程序包可能与您的项目不完全兼容。
  • Microsoft.PowerShell.SDK-仅适用于PowerShell 7,不适用于Windows PowerShell 5.1
  • PowerShellLibrary.Standard-我认为这不适用于应用程序中的托管PowerShell

我可以通过只调用一个新进程来解决这个问题:

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();

这是可行的,但话虽如此,如果可能的话,我宁愿使用受支持的SDK或引用程序集。特别是为了更容易地实现运行空间,以及让PowerShell主机在不挂起UI的情况下在单独的线程上运行。
我发现了这个:https://devblogs.microsoft.com/powershell/depending-on-the-right-powershell-nuget-package-in-your-net-project/
是否不支持/不可能在WinUI3.Net Core应用程序中托管Windows PowerShell 5.1?任何帮助都将不胜感激,我通常是PowerShell用户,而不是C#开发人员,但我正在跌跌撞撞地度过难关。

uurv41yg

uurv41yg1#

tl;dr

  • 在.NET(核心)应用程序中托管Windows PowerShell SDK是*不可能的,因为您已经确认了via Twitter
  • 通过其CLI powershell.exe子进程中调用PowerShell可能确实是您唯一的选择。

让我们先来回顾一下:
由于Windows PowerShell是基于传统的、仅适用于Windows的.NET框架(而不是它的后续版本,即跨平台的.NET Core/.NET 5+框架),因此NuGet SDK包也是如此,它允许在应用程序Microsoft.PowerShell.5.1.ReferenceAssemblies中托管Windows PowerShell。
您的项目以.NET 6.0(net60)为目标,这就是为什么您在构建项目时会看到有关目标框架不匹配的警告。
虽然这只是一个警告,而不是一个错误,这表明这种不匹配的组合可能在情况下仍然有效,但这不是尝试在.NET(Core)6.0应用程序中托管Windows PowerShell的情况:在尝试示例化PowerShell类时抛出异常*:System.InvalidProgramException: Common Language Runtime detected an invalid program.
使用Microsoft.Windows.Compatibility package(在this article中讨论)无济于事。
因此,通过其CLIpowershell.exe作为“子进程”调用Windows PowerShell确实是您的最佳选择。
除了速度慢和资源密集型外,另一个缺点是只能接收文本输出。

guicsvcw

guicsvcw2#

还有另一种选择,使用PowerShell SDK,这并没有很好的文档。您可以使用进程外运行空间

using var runspace = RunspaceFactory.CreateOutOfProcessRunspace(
    new TypeTable(Array.Empty<string>()),
    new PowerShellProcessInstance(new Version(5, 1), null, null, false)
);
using var instance = PowerShell.Create(runspace);

这允许使用完整的SDK,以及带来的所有好处。在幕后,这将启动Windows PowerShell进程。当然,这在除Windows之外的任何其他平台上都会失败。

相关问题