Runspace忽略自定义PSHostUserInterface

Mik*_*ley 4 c# powershell runspace

的背景

我正在编写一个以编程方式执行PowerShell脚本的应用程序.此应用程序具有自定义PSHost实现,以允许脚本输出日志记录语句.目前,我看到的行为是某些请求被正确转发到我的自定义PSHost而其他请求被忽略了.

当我开始检查$Host脚本中的变量时,事情变得更加奇怪,这似乎表明我的自定义PSHost甚至没有被使用.

代码

我有一些代码在.NET应用程序中执行PowerShell:

var state = InitialSessionState.CreateDefault();
state.AuthorizationManager = new AuthorizationManager("dummy"); // Disable execution policy

var host = new CustomPsHost(new CustomPsHostUI());

using (var runspace = RunspaceFactory.CreateRunspace(host, state))
{
    runspace.Open();

    using (var powershell = PowerShell.Create())
    {
        powershell.Runspace = runspace;

        var command = new Command(filepath);

        powershell.Invoke(command);
    }
}
Run Code Online (Sandbox Code Playgroud)

实现CustomPsHost非常简单,只包含转发所需的内容PSHostUserInterface:

public class CustomPsHost : PSHost
{
    private readonly PSHostUserInterface _hostUserInterface;

    public CustomPsHost(PSHostUserInterface hostUserInterface)
    {
        _hostUserInterface = hostUserInterface;
    }

    public override PSHostUserInterface UI
    {
        get { return _hostUserInterface; }
    }

    // Methods omitted for brevity
}
Run Code Online (Sandbox Code Playgroud)

CustomPsHostUI用作日志记录的包装器:

public class CustomPsHostUI : PSHostUserInterface
{
    public override void Write(string value) { Debug.WriteLine(value); }
    public override void Write(ConsoleColor foregroundColor, ConsoleColor backgroundColor, string value){ Debug.WriteLine(value); }
    public override void WriteLine(string value) { Debug.WriteLine(value); }
    public override void WriteErrorLine(string value) { Debug.WriteLinevalue); }
    public override void WriteDebugLine(string message) { Debug.WriteLine(message); }
    public override void WriteProgress(long sourceId, ProgressRecord record) {}
    public override void WriteVerboseLine(string message) { Debug.WriteLine(message); }

    // Other methods omitted for brevity
}
Run Code Online (Sandbox Code Playgroud)

在我的PowerShell脚本中,我正在尝试向主机写入信息:

Write-Warning "This gets outputted to my CustomPSHostUI"
Write-Host "This does not get outputted to the CustomPSHostUI"

Write-Warning $Host.GetType().FullName # Says System.Management.Automation.Internal.Host.InternalHost
Write-Warning $Host.UI.GetType().FullName # Says System.Management.Automation.Internal.Host.InternalHostUserInterface
Run Code Online (Sandbox Code Playgroud)

我为什么要和我一起做出奇怪的行为CustomPSHostUI

Jas*_*irk 6

您需要为PSHostRawUserInterface提供实现.

Write-Host最终调用你的Write(ConsoleColor,ConsoleColor,string)版本.PowerShell依赖于前景色和背景色的原始ui实现.

我已通过示例代码验证了这一点.我没有调用ps1文件,而是直接调用了Write-Host:

powershell.AddCommand("Write-Host").AddParameter("Testing...")
Run Code Online (Sandbox Code Playgroud)

通过运行脚本,PowerShell正在为您处理异常.通过直接调用命令,您可以更轻松地查看异常.如果您在原始示例中检查过$ error,则会看到一个有用的错误.

请注意,$ host的值永远不是实际的实现.PowerShell通过包装来隐藏实际的实现.我忘记了为什么它被包裹的确切细节.