【问题标题】:C# Runspace Powershell (Interactive)C# Runspace Powershell(交互式)
【发布时间】:2014-11-15 19:09:54
【问题描述】:

我正在尝试使用 C# 在运行空间中执行带有参数的 Powershell 文件。不幸的是,我得到以下输出:

提示用户失败的命令,因为主机程序或 命令类型不支持用户交互。尝试主机程序 支持用户交互,例如 Windows PowerShell 控制台 或 Windows PowerShell ISE,并从 不支持用户交互的命令类型,例如 Windows PowerShell 工作流程。

我能做什么?

当前的 c# 代码。这需要执行将在 PS 文件中的命令,并且需要返回一个 json 字符串。

public string ExecuteCommandDirect(int psId, string psMaster, string psFile)
{
    String FullPsFilePath = @"C:\CloudPS\" + psFile + ".ps1";

    String PsParameters = FullPsFilePath + " -psId " + psId + " -psMaster " + psMaster + " -NonInteractive";

    // Create Powershell Runspace
    Runspace runspace = RunspaceFactory.CreateRunspace();

    runspace.Open();

    // Create pipeline and add commands
    Pipeline pipeline = runspace.CreatePipeline();
    pipeline.Commands.AddScript(PsParameters);

    // Execute Script
    Collection<PSObject> results = new Collection<PSObject>();
    try
    {
        results = pipeline.Invoke();
    }
    catch (Exception ex)
    {
        results.Add(new PSObject((object)ex.Message));
    }

    // Close runspace
    runspace.Close();

    //Script results to string
    StringBuilder stringBuilder = new StringBuilder();
    foreach (PSObject obj in results)
    {
        Debug.WriteLine(obj);
        stringBuilder.AppendLine(obj.ToString());
    }

    return stringBuilder.ToString();

}

PS 代码:

param([int]$psId = 0, [string]$psMaster = 'localhost');

$date = Get-Date -Format 'h:m:s' | ConvertTo-Json;

Write-Host $date;

exit;

【问题讨论】:

  • 你能贴出你正在使用的代码吗?
  • 嗨,我已经添加了代码。
  • 尝试删除Write-Host,只留下$dateexit 也不需要。
  • 如果您想使用需要主机的 cmdlet,您需要创建一个运行空间并传递一个 PSHost 实例。像 Write-Host 或 Read-Host 这样的 Cmdlet 实际上要求您还实现从 PSHost 实例上的属性返回的 PSHostUserInterface。 AFAIK 这些抽象类没有默认的公共实现。您必须自己编写它们,但是there are some examples available on MSDN.
  • 有关如何实现它们的示例(或仅使用 ps1 -> exe 包装器)请参阅此博客文章 - rkeithhill.wordpress.com/2010/09/21/make-ps1exewrapper

标签: c# powershell runspace


【解决方案1】:

如果您需要运行使用非关键 cmdlet 的脚本,例如 write-host,需要存在完整的 pshost,您可以将“假”函数添加到运行空间,这些函数要么什么都不做,要么记录到文本文件(或您想要的任何其他内容。)在此处查看我的其他答案:

How can I execute scripts in a code created powershell shell that has Write-Host commands in it?

【讨论】:

    【解决方案2】:

    使用Write-Output 代替Write-Host

    【讨论】:

    • 我用谷歌搜索、点击、滚动并看到了这个答案。我从 -Host 切换到 -Output 并停止收到 OP 发布的错误消息。这个答案不仅正确而且简洁有用。
    • 工作完美。
    【解决方案3】:

    通过覆盖这两个 cmdlet,我自己解决了 Read-Host 和 Write-Host 的这个问题。在我的解决方案中,我默默地丢弃了发送到 Write-Host 的任何内容,但我需要实现 Read-Host。这将启动一个新的 powershell 进程并返回结果。

            string readHostOverride = @"
                function Read-Host {
                    param(
                        [string]$Prompt
                    )
    
    
    
                    $StartInfo = New-Object System.Diagnostics.ProcessStartInfo
                    #$StartInfo.CreateNoWindow = $true 
                    $StartInfo.UseShellExecute = $false 
                    $StartInfo.RedirectStandardOutput = $true 
                    $StartInfo.RedirectStandardError = $true 
                    $StartInfo.FileName = 'powershell.exe' 
                    $StartInfo.Arguments = @(""-Command"", ""Read-Host"", ""-Prompt"", ""'$Prompt'"")
                    $Process = New-Object System.Diagnostics.Process
                    $Process.StartInfo = $StartInfo
                    [void]$Process.Start()
                    $Output = $Process.StandardOutput.ReadToEnd() 
                    $Process.WaitForExit() 
                    return $Output.TrimEnd()
                }
            ";
    
            string writeHostOverride = @"
                function Write-Host {
                }
            ";
    
            Run(readHostOverride);
            Run(writeHostOverride);
    

    Run() 毫无疑问是我执行 powershell 的方法。

    您也可以轻松扩展它以实现 Write-Host;如果您有任何困难,请告诉我。

    对于建议切换到 Write-Output 而不是 Write-Host 的评论者,这不是许多用例的解决方案。例如,您可能不希望您的用户通知进入您的输出流。

    如果您需要使用原始 cmdlet,请使用:

    Microsoft.PowerShell.Utility\Read-Host -Prompt "Enter your input"
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-04-05
      • 1970-01-01
      • 2015-08-04
      • 1970-01-01
      • 2017-03-08
      • 1970-01-01
      • 2014-06-01
      相关资源
      最近更新 更多