运行 C# 应用程序中的 PowerShell 进程并与之交互
Run a PowerShell process in a C# app and interact with it
我正在创建一个需要与 PowerShell 交互的 C#/WPF 应用程序(基本上,运行 命令和脚本)。创建进程并启动它不是问题,这很容易,但是当目标是在没有任何脚本的情况下启动它并在以后使其成为 运行 命令和脚本时变得更加困难:
- 启动 C# 应用程序
- 运行 PowerShell 并行处理
- [...] 做一些其他事情 [...]
- 运行 进程上的命令
我尝试了多种解决方案。
使用 System.Diagnostics.Process
class,我可以启动进程,让它 运行,但即使我重定向流,写入标准输入也不起作用:
var startInfo = new ProcessStartInfo()
{
FileName = "powershell.exe",
Arguments = "-ExecutionPolicy Bypass -NoLogo -NoExit",
CreateNoWindow = true,
RedirectStandardError = true,
RedirectStandardInput = true,
RedirectStandardOutput = true,
UseShellExecute = false,
WindowStyle = ProcessWindowStyle.Hidden
};
_ps = new Process()
{
EnableRaisingEvents = true,
StartInfo = startInfo
};
_ps.Start();
[...]
_ps.StandardInput.WriteLine(TextBox_Input.Text); // No effect
使用 System.Management.Automation.PowerShell
class 不是更好,我可以准备管道(添加要执行的脚本),调用它,但是,我不能 运行 稍后保留脚本进程还活着。
我需要尽快启动进程以便能够向它发送命令并运行它们越快越好(并避免进程启动会导致延迟)。
如评论中所述,在应用程序启动时设置(并打开)运行空间:
Runspace rs;
public MainWindow()
{
InitializeComponent();
rs = RunspaceFactory.CreateRunspace();
rs.Open();
}
现在,您只需要一个创建 PowerShell
实例并在运行空间中执行它的函数:
private Collection<PSObject> RunScript(string script)
{
using(PowerShell ps = PowerShell.Create())
{
ps.AddScript(script);
ps.Runspace = rs;
return ps.Invoke();
}
}
然后,在 运行 的事件处理程序中,用户输入的脚本:
private void button_Click(object sender, RoutedEventArgs e)
{
Collection<PSObject> returnedObjects = RunScript(TextBox_Input.Text);
// do what you want with returnedObjects if necessary
}
这当然是一个过于简化的示例。在实际应用程序中,您将检查 error and warning streams、使用 APM (BeginInvoke()
/EndInvoke()
) 等
我正在创建一个需要与 PowerShell 交互的 C#/WPF 应用程序(基本上,运行 命令和脚本)。创建进程并启动它不是问题,这很容易,但是当目标是在没有任何脚本的情况下启动它并在以后使其成为 运行 命令和脚本时变得更加困难:
- 启动 C# 应用程序
- 运行 PowerShell 并行处理
- [...] 做一些其他事情 [...]
- 运行 进程上的命令
我尝试了多种解决方案。
使用 System.Diagnostics.Process
class,我可以启动进程,让它 运行,但即使我重定向流,写入标准输入也不起作用:
var startInfo = new ProcessStartInfo()
{
FileName = "powershell.exe",
Arguments = "-ExecutionPolicy Bypass -NoLogo -NoExit",
CreateNoWindow = true,
RedirectStandardError = true,
RedirectStandardInput = true,
RedirectStandardOutput = true,
UseShellExecute = false,
WindowStyle = ProcessWindowStyle.Hidden
};
_ps = new Process()
{
EnableRaisingEvents = true,
StartInfo = startInfo
};
_ps.Start();
[...]
_ps.StandardInput.WriteLine(TextBox_Input.Text); // No effect
使用 System.Management.Automation.PowerShell
class 不是更好,我可以准备管道(添加要执行的脚本),调用它,但是,我不能 运行 稍后保留脚本进程还活着。
我需要尽快启动进程以便能够向它发送命令并运行它们越快越好(并避免进程启动会导致延迟)。
如评论中所述,在应用程序启动时设置(并打开)运行空间:
Runspace rs;
public MainWindow()
{
InitializeComponent();
rs = RunspaceFactory.CreateRunspace();
rs.Open();
}
现在,您只需要一个创建 PowerShell
实例并在运行空间中执行它的函数:
private Collection<PSObject> RunScript(string script)
{
using(PowerShell ps = PowerShell.Create())
{
ps.AddScript(script);
ps.Runspace = rs;
return ps.Invoke();
}
}
然后,在 运行 的事件处理程序中,用户输入的脚本:
private void button_Click(object sender, RoutedEventArgs e)
{
Collection<PSObject> returnedObjects = RunScript(TextBox_Input.Text);
// do what you want with returnedObjects if necessary
}
这当然是一个过于简化的示例。在实际应用程序中,您将检查 error and warning streams、使用 APM (BeginInvoke()
/EndInvoke()
) 等