C#Runspace Powershell(交互式)

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

A command that prompts the user failed because the host program or the command type does not support user interaction. Try a host program that supports user interaction, such as the Windows PowerShell Console or Windows PowerShell ISE, and remove prompt-related commands from command types that do not support user interaction, such as Windows PowerShell workflows. 

我能做什么?

当前的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 results = new Collection(); 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; 

如果需要运行使用非关键cmdlet(如write-host)的脚本,需要存在完全成熟的pshost,则可以向运行空间添加“伪”函数,这些函数不执行任何操作或登录到文本文件(或你想要的任何其他东西。)在这里看到我的其他答案:

如何在代码中创建具有Write-Host命令的powershell shell中的脚本?

使用Write-Output而不是Write-Host

我已经通过覆盖这两个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; 如果您有任何困难,请告诉我。

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

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

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