Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/291.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#运行空间Powershell(交互式)_C#_Powershell_Runspace - Fatal编程技术网

C#运行空间Powershell(交互式)

C#运行空间Powershell(交互式),c#,powershell,runspace,C#,Powershell,Runspace,我正在尝试使用C#在运行空间中使用参数执行Powershell文件。不幸的是,我得到了以下输出: 提示用户的命令失败,因为主机程序或 命令类型不支持用户交互。尝试主机程序 支持用户交互的,如Windows PowerShell控制台 或Windows PowerShell ISE,并从中删除与提示相关的命令 不支持用户交互的命令类型,如Windows PowerShell工作流 我能做什么 当前c#代码。这需要执行PS文件中的命令,并且需要返回json字符串 public string Exec

我正在尝试使用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();

}

如果需要运行使用非关键cmdlet(如write host)的脚本,而该脚本需要一个完全成熟的pshost,则可以向运行空间添加“假”函数,这些函数可以不执行任何操作,也可以记录到文本文件(或任何您想要的内容)。请参见此处的其他答案:


使用
写入输出
而不是
写入主机
通过覆盖这两个cmdlet,我自己解决了读主机和写主机的此问题。在我的解决方案中,我默默地删除发送给写主机的任何内容,但我需要实现读主机。这将启动一个新的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的方法

您可以轻松地扩展它来实现写主机;如果你有任何困难,请告诉我

对于建议切换到写输出而不是写主机的评论员来说,这不是许多用例的解决方案。例如,您可能不希望用户通知进入输出流

如果需要使用原始cmdlet,请使用以下命令:

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

您可以发布您正在使用的代码吗?您好,我已经添加了代码。请尝试删除
Write Host
,只保留
$date
<代码>退出也不需要。如果要使用需要主机的cmdlet,则需要创建运行空间并传递PSHost实例。诸如Write-Host或Read-Host之类的cmdlet实际上还需要实现从PSHost实例上的属性返回的PSHostUserInterface。AFAIK这些抽象类没有默认的公共实现。您必须自己编写它们,然而,关于如何实现它们的示例(或仅使用ps1->exe包装器),请参阅此博客文章-我在谷歌上搜索、单击、滚动并看到了此答案。我从-Host切换到-Output,并停止接收OP发布的错误消息。这个答案不仅正确,而且简洁且有用。工作非常完美。
Microsoft.PowerShell.Utility\Read-Host -Prompt "Enter your input"