退出代码 0 在 c# 中不显示 ps1 文件的结果和传递参数

Exit code 0 does not show the result and passing argument for ps1 file in c#

我正在尝试通过 C# 代码中的 PowerShell 运行 Windows 子系统的 Linux (WSL) 的功能之一。即使没有错误,我也看不到结果。为了修复它,我已经阅读并实施了其他 Whosebug 问题中的一些建议,但我仍然看不到结果。另一个问题是是否可以为以下代码传递参数。在 MS 网站上,没有关于传递参数的示例。我希望有办法做到这一点。

代码在这里:

PowerShell ps = PowerShell.Create();
ps.AddScript(File.ReadAllText(@"C:\Users\username\Desktop\test.ps1"));
ps.Invoke();  

调试的输出是:

The thread 0x4034 has exited with code 0 (0x0).
The thread 0x4b34 has exited with code 0 (0x0).
The thread 0x4f0 has exited with code 0 (0x0).
The program '[18876] WSL_CS.exe' has exited with code 0 (0x0).

但是命令提示符的打开和关闭速度非常快。

在 PowerShell 中,当我 运行 下面的代码时,我可以看到结果。

powershell -ExecutionPolicy Bypass -File test.ps1 5

如果您希望启动一个执行脚本文件并保持打开状态的可见控制台window(脚本退出后进入交互式会话):

  • 请勿使用 PowerShell SDK 及其 PowerShell .NET class:其目的是 程序化 控制 PowerShell 命令,不可见,交互式执行。

  • 相反,在可见控制台中使用通用 Process class to create a child process that launches the PowerShell CLI window(默认):

System.Diagnostics.Process.Start(
  "powershell.exe",  // The Windows PowerShell CLI
  @"-ExecutionPolicy Bypass -NoExit -NoLogo -File C:\Users\username\Desktop\test.ps1 5"
).WaitForExit();

注意传递给脚本文件的参数是如何在脚本文件路径之后指定的(本例中为 5)- 请务必根据需要将它们用双引号引起来,例如何时它们包含嵌入式空格。

由于 -File (-f) 之后的所有内容都被解释为脚本文件路径和传递给脚本的参数,因此请务必将这些参数放在 last 在命令行上。

或者,如果您要创建 .NET Core / .NET 5+ 应用程序,您可以 单独指定所有参数 ,在这种情况下,.NET 会为您处理所有需要的双引号:

System.Diagnostics.Process.Start(
  "powershell.exe",  // The Windows PowerShell CLI
   new string[] {
     "-ExecutionPolicy",
     "Bypass",
     "-NoExit",
     "-NoLogo",
     "-File",
     @"C:\Users\jdoe\Desktop\pg\pg.ps1",
     "5"  // Pass-through arguments.
   }
).WaitForExit();

陷阱:

    如果传递给 -File 的脚本文件无法找到
  • -NoExit 不会 受到尊重。
    • 这与将一段 PowerShell 源代码传递给 -Command (-c) 参数形成对比,其中 -NoExit ,即使执行源代码导致错误)。
    • 这种差异可以说是一个 错误 并且已在 GitHub issue #10471.
    • 中报告

结果是,如果您不是从 现有 控制台 window 启动进程,则会按需创建一个控制台 window,后不久自动关闭,即在 PowerShell 因未找到指定的脚本文件而报告错误后,几乎无法看到发生了什么。

变通方法是改用-Command参数,这样可以无条件打开window:

// Again, passing arguments individually is an option in .NET Core / .NET 5+
System.Diagnostics.Process.Start(
  "powershell.exe",  // The Windows PowerShell CLI
  @"-ExecutionPolicy Bypass -NoExit -NoLogo -Command & C:\Users\username\Desktop\test.ps1 5"
).WaitForExit();

请注意使用 &call operator 来调用脚本(在 这种情况下 ,这不是绝对必要的,但通常是如果脚本文件路径是 quoted and/or 包含变量引用)。

另请注意,使用 -Command 会更改传递参数的解释方式,这可能会或可能不会导致问题(不是使用简单的参数,例如 5);简而言之:在命令行解析之后,在此期间 syntactic(未转义)" 个字符。被剥离,PowerShell 然后 将生成的参数解释为 PowerShell 源代码,对它们进行额外的解释层 - 请参阅 更多信息。