[英]How to answer to Read-Host from C# code that invoked that PowerShell script?
我需要从我的 C# 代码中运行 PowerShell 脚本。 那很容易。 但是,我的 PowerShell 脚本包含几个 Read-Host 命令。 通常,脚本执行会停止,用户应该手动向 PowerShell 控制台输入一些值作为答案。 但我需要的是从执行和控制该脚本流程的 C# 中的相同代码响应这些读取主机请求。 换句话说,我需要我的脚本在某个时候停止并等待从我的 C# 代码输入一些数据,然后获取它并继续执行。
我找到了如何从 C# 运行 PS,我找到了如何在启动它时将参数或初始变量从 C# 传递到 PS 脚本,但我找不到任何方法如何让我的脚本等待来自主机应用程序的一些数据,接收它并在主机应用程序中继续执行,所有这些都在脚本运行时,而不是在其启动时。
你能指导我一些可能有帮助的搜索或代码方向吗?
您可以在流程的StandardInput
上调用WriteLine()
。 这将为脚本中的一个Read-Host
提供数据。
为此,请确保将相应ProcessStartInfo
UseShellExecute
设置为false
并将其RedirectStandardInput
为true
。
所以例如
Process p = Process.Start(new ProcessStartInfo()
{
FileName = "powershell",
Arguments = @"C:\Users\Konstantin\ps.ps1",
UseShellExecute = false,
RedirectStandardInput = true,
});
p.StandardInput.WriteLine("abc");
将为脚本C:\\Users\\Konstantin\\ps.ps1
的第一个Read-Host
提供“abc”。
如果有更多Read-Host
再次调用WriteLine()
。 或者,您可以将字符串连接与StandardInput.NewLine
一起使用,然后只使用Write
。 例如
p.StandardInput.Write("abc" + StandardInput.NewLine + "xyz" + StandardInput.NewLine);
将为第一个提供“abc”,为第二个Read-Host
提供“xyz”。
如果您在进程内调用 PowerShell 脚本,则覆盖Read-Host
行为的唯一方法是为该进程定义自定义PSHost
。 该行为由方法PSHostUserInterface.ReadLine
定义。 这是您只需要覆盖Read-Host
最低限度示例。
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Management.Automation;
using System.Management.Automation.Host;
using System.Management.Automation.Runspaces;
using System.Security;
namespace CustomHostExample
{
public static class Program
{
public static void Main()
{
var host = new CustomPSHost();
using (Runspace rs = RunspaceFactory.CreateRunspace(host))
using (PowerShell pwsh = PowerShell.Create())
{
rs.Open();
pwsh.Runspace = rs;
pwsh.AddCommand("Read-Host").Invoke();
}
}
}
public class CustomPSHost : PSHost
{
public override string Name => "Custom Host";
public override Version Version => new Version(1, 0, 0, 0);
public override Guid InstanceId { get; } = Guid.NewGuid();
public override PSHostUserInterface UI { get; } = new CustomPSHostUserInterface();
public override CultureInfo CurrentCulture => CultureInfo.CurrentCulture;
public override CultureInfo CurrentUICulture => CultureInfo.CurrentUICulture;
public override void EnterNestedPrompt()
=> throw new NotImplementedException();
public override void ExitNestedPrompt()
=> throw new NotImplementedException();
public override void NotifyBeginApplication()
=> throw new NotImplementedException();
public override void NotifyEndApplication()
=> throw new NotImplementedException();
public override void SetShouldExit(int exitCode)
=> throw new NotImplementedException();
}
public class CustomPSHostUserInterface : PSHostUserInterface
{
public override PSHostRawUserInterface RawUI { get; } = new CustomPSHostRawUserInterface();
public override string ReadLine()
{
return Console.ReadLine();
}
public override Dictionary<string, PSObject> Prompt(
string caption,
string message,
Collection<FieldDescription> descriptions)
=> throw new NotImplementedException();
public override int PromptForChoice(
string caption,
string message,
Collection<ChoiceDescription> choices,
int defaultChoice)
=> throw new NotImplementedException();
public override PSCredential PromptForCredential(
string caption,
string message,
string userName,
string targetName,
PSCredentialTypes allowedCredentialTypes,
PSCredentialUIOptions options)
=> throw new NotImplementedException();
public override PSCredential PromptForCredential(
string caption,
string message,
string userName,
string targetName)
=> throw new NotImplementedException();
public override SecureString ReadLineAsSecureString()
=> throw new NotImplementedException();
public override void Write(ConsoleColor foregroundColor, ConsoleColor backgroundColor, string value)
=> throw new NotImplementedException();
public override void Write(string value)
=> throw new NotImplementedException();
public override void WriteDebugLine(string message)
=> throw new NotImplementedException();
public override void WriteErrorLine(string value)
=> throw new NotImplementedException();
public override void WriteLine(string value)
=> throw new NotImplementedException();
public override void WriteProgress(long sourceId, ProgressRecord record)
=> throw new NotImplementedException();
public override void WriteVerboseLine(string message)
=> throw new NotImplementedException();
public override void WriteWarningLine(string message)
=> throw new NotImplementedException();
}
public class CustomPSHostRawUserInterface : PSHostRawUserInterface
{
public override ConsoleColor BackgroundColor
{
get => throw new NotImplementedException();
set => throw new NotImplementedException();
}
public override Size BufferSize
{
get => throw new NotImplementedException();
set => throw new NotImplementedException();
}
public override Coordinates CursorPosition
{
get => throw new NotImplementedException();
set => throw new NotImplementedException();
}
public override int CursorSize
{
get => throw new NotImplementedException();
set => throw new NotImplementedException();
}
public override ConsoleColor ForegroundColor
{
get => throw new NotImplementedException();
set => throw new NotImplementedException();
}
public override Coordinates WindowPosition
{
get => throw new NotImplementedException();
set => throw new NotImplementedException();
}
public override Size WindowSize
{
get => throw new NotImplementedException();
set => throw new NotImplementedException();
}
public override string WindowTitle
{
get => throw new NotImplementedException();
set => throw new NotImplementedException();
}
public override bool KeyAvailable
=> throw new NotImplementedException();
public override Size MaxPhysicalWindowSize
=> throw new NotImplementedException();
public override Size MaxWindowSize
=> throw new NotImplementedException();
public override void FlushInputBuffer()
=> throw new NotImplementedException();
public override BufferCell[,] GetBufferContents(Rectangle rectangle)
=> throw new NotImplementedException();
public override KeyInfo ReadKey(ReadKeyOptions options)
=> throw new NotImplementedException();
public override void ScrollBufferContents(
Rectangle source,
Coordinates destination,
Rectangle clip,
BufferCell fill)
=> throw new NotImplementedException();
public override void SetBufferContents(Coordinates origin, BufferCell[,] contents)
=> throw new NotImplementedException();
public override void SetBufferContents(Rectangle rectangle, BufferCell fill)
=> throw new NotImplementedException();
}
}
注意:所示的每个不抛出NotImplementedException
必须实现,否则 PowerShell 将死锁或抛出。 根据调用PSHost
其他内容,需要实现更多方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.