18

我试图在我的应用程序中添加一些相当有限的 PowerShell 支持:我希望能够定期运行用户定义的 PowerShell 脚本并显示任何输出,并且(最终)能够处理进度通知和用户提示请求。我不需要命令行样式的交互支持,或者(我认为)远程访问或运行多个同时脚本的能力,除非用户脚本在我托管的 shell 中自行完成。我最终希望异步运行脚本或在后台线程上运行脚本,并且可能使用一些初始变量和可能的 cmdlet 为 shell 播种,但这与此功能可能获得的一样“花哨”。

我一直在阅读有关编写主机应用程序代码的 MSDN 文档,但是虽然它愉快地解释了如何创建PowerShell对象,或Runspace,或RunspacePool,或Pipeline,但没有任何迹象表明为什么人们会选择这些方法中的任何一种而不是另一种。

我只能选择这两种方法中的一种,但我喜欢一些关于哪种方法更好的反馈:

PowerShell shell = PowerShell.Create();
shell.AddCommand(/* set initial state here? */);
shell.AddStatement();
shell.AddScript(myScript);
shell.Invoke(/* can set host! */);

或者:

Runspace runspace = RunspaceFactory.CreateRunspace(/* can set host and initial state! */);
PowerShell shell = PowerShell.Create();
shell.Runspace = runspace;
shell.AddScript(myScript);
shell.Invoke(/* can set host here, too! */);

(必需的PSHost派生类方法之一是EnterNestedPrompt(),我不知道我运行的用户定义脚本是否会导致它被调用。如果可以,那么我将负责“启动一个新的嵌套输入循环”(根据这里)......如果这会影响上面采取的路径,那也很高兴知道。)

谢谢!

4

2 回答 2

4

这些是什么?

  • 管道

Pipeline 是一种在 powershell 脚本中连接命令的方法。示例:您将输出从“管道”Get-ChildeItemWhere-Objectwith|以过滤它们:

Get-ChildItem | Where-Object {$_}
  • PowerShell 对象

PowerShell 对象指的是一个 powershell 会话,就像您在启动 powershell.exe 时所获得的一样。

  • 运行空间

每个 powershell 会话都有自己的运行空间(您将始终从 获得输出Get-Runspace)。它定义了 powershell 会话的状态。因此,运行空间的InitialSessionState对象/属性。您可能决定创建一个新的 powershell 会话,它在 powershell 中具有自己的运行空间,以启用一种多线程。

  • 运行空间池

最后但并非最不重要的是 RunspacePool。顾名思义,它是一个运行空间池(或 powershell 会话),可用于处理许多复杂的任务。一旦池中的一个运行空间完成其任务,它可能会执行下一个任务,直到一切都完成。(与 10 个运行空间有关的 100 件事:平均而言,它们每个处理 10 个,但一个可能处理 8 个,而另外两个处理 11 个......)


什么时候用什么?

  • 管道

管道用于插入脚本。它使构建复杂的脚本变得更加容易,并且应该尽可能频繁地使用。

  • PowerShell 对象

当您需要新的 powershell 会话时,将使用 powershell 对象。您可以在现有脚本中创建一个,无论是 C# 还是 Powershell。它对于简单的多线程很有用。它自己会创建一个默认会话。

  • 运行空间

如果要创建非标准的 powershell 会话,可以在使用它创建 powershell 会话之前操作运行空间对象。当您想在额外的运行空间中共享同步变量、函数或类时,它很有用。稍微复杂的多线程。

  • 运行空间池

如前所述,它是用于繁重工作的重型工具。当一个脚本的执行需要几个小时并且您需要经常执行时。例如,结合远程处理,您可以在大型集群的每个节点等上同时安装一些东西。

于 2019-01-29T09:40:23.180 回答
0

你想多了。您在示例中显示的代码是一个好的开始。现在您只需要阅读结果Invoke()并检查错误和警告流。

PowerShell 主机提供了一些 RunSpace 可以用来与用户通信的钩子,例如流和格式输出、显示进度、报告错误等。对于您想要做的事情,您不需要 PowerShell 主机。您可以使用 PowerShell 类从脚本执行中读取结果、检查错误、警告、读取输出流并使用应用程序的工具向用户显示通知。这将比编写整个 PowerShell 主机以在检测到错误时显示消息框更直接和有效。

此外,PowerShell 对象在创建时有一个运行空间,您不需要给它一个。如果您需要保留运行空间以保留环境,只需在每次调用 Invoke 后保留整个 PowerShell 对象并清除命令和所有流。

您应该问的下一个问题是如何处理PowerShell::Invoke()和读取的结果PowerShell::Streams

于 2014-01-10T20:24:50.270 回答