【问题标题】:Async write to the PowerShell host异步写入 PowerShell 主机
【发布时间】:2012-12-11 06:18:31
【问题描述】:

我正在编写一些旨在(也)与PowerShell 一起使用的对象。 我希望能够以异步方式直接写入PowerShell 控制台。 到目前为止,我做了以下事情:

  • 创建了一个 IUtilityHost 接口,该接口公开了一些方法,例如 WriteLine
  • 我在 PSUtilityHost 中实现了接口:包装了 PSHost 对象的 IUtilityHost 类
  • 实现WriteLine方法是在PSHost.UI对象上调用WriteLine方法实现的。

问题是我有一个奇怪的输出混合了 Read-Host 消息,我有时需要在需要手动输入时阻止执行。

我想知道是否有更好的方法将消息异步发送到 powershell 主机。

谢谢

【问题讨论】:

  • 您是否正在创建自己的 PowerShell 主机?如果是这样,您可以完全控制主机 UI 实现。如果不是,您的代码是否需要写入主机,始终使用 cmdlet 的执行上下文运行?或者,用户是否可以在脚本中调用您的对象,然后该对象会写入主机(在 cmdlet 调用的上下文之外)?
  • 在第一个实例中,我想使用 PowerShell 控制台的默认 PSHost,但稍后我想将它也用于其他自定义主机。这就是为什么我更喜欢使用标准方法和模式。该对象存在于一个脚本中,但本质上是一个双工 WCF 服务,我想将请求日志写入 PowerShell 控制台,以便我可以使用某些特定方法“回复”客户端。因此,该对象位于 cmdlet 调用的上下文之外。

标签: c# powershell


【解决方案1】:

尝试从 C# 中获取 Host 对象并使用其 Write* 方法来执行此操作,例如:

public class Poco
{
    private PSHostUserInterface _ui;

    public Poco()
    {
        var runspace = Runspace.DefaultRunspace;
        Pipeline pipeline = runspace.CreateNestedPipeline("Get-Variable host -ValueOnly", false);
        Collection<PSObject> results = pipeline.Invoke();
        if (results.Count > 0)
        {
            var host = results[0].BaseObject as PSHost;
            if (host != null)
            {
                _ui = host.UI;
            }
        }            
    }

    public void WriteLine(string msg)
    {
        _ui.WriteLine(msg);
    }
}

注意:虽然您可以只使用 Console.WriteLine 来为 PowerShell 提示符执行此操作,但对于不是控制台应用程序的其他 PowerShell 主机(如 ISE)没有帮助。

【讨论】:

  • 这或多或少是我的解决方案(我在构造函数中传递主机)。无论如何,创建一个嵌套管道为我抛出了异常(我试图做一个更清洁的 Write-Host)。更多,我想要一个更好的输出,因为像这样它与 Read-Host 消息混合在一起。我正在考虑类似于 Write-Progress 的行为......但我不知道是否有预定义的方式在 UI 上显示“覆盖/消息”。
  • 附加细节:如果我阻止脚本等待输入 Read-Host 我可以在控制台中看到传入的消息;如果我使用普通控制台,只有当我输入 enter 时才会刷新所有消息(我使用的是 PSHost.UI.WriteXXX 方法)。
  • @fr 我必须在 ctor 中创建嵌套管道,因为我是从 PowerShell 调用它,即在管道中。另一种选择是下拉到 UI.RawUI 并操作显示中的各个单元格。
猜你喜欢
  • 2018-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多