【发布时间】:2017-10-30 23:53:01
【问题描述】:
我们有一个执行 PowerShell 脚本作为扩展点的 C# 应用程序,我们无权更改此代码,但大致如下:
string command = @"C:\temp.ps1";
var fileName = "powershell";
var args = $"-ExecutionPolicy unrestricted . '{command}'";
var process = CreateProcess(fileName, args);
ExecuteProcess(ref process);
private Process CreateProcess(string fileName, string args)
{
return new Process
{
StartInfo =
{
FileName = fileName,
Arguments = args,
RedirectStandardError = true,
RedirectStandardOutput = true,
UseShellExecute = false
}
};
}
private int ExecuteProcess(ref Process proc)
{
proc.Start();
string text = string.Empty;
string text2 = string.Empty;
while (!proc.HasExited)
{
Thread.Sleep(1000);
text += proc.StandardOutput.ReadToEnd();
text2 += proc.StandardError.ReadToEnd();
}
proc.WaitForExit();
text2 += proc.StandardError.ReadToEnd();
text += proc.StandardOutput.ReadToEnd();
Console.WriteLine(text);
Console.WriteLine(text2);
return proc.ExitCode;
}
我们有一个 PowerShell 脚本,该脚本从该代码执行,该代码有一个长时间运行的过程,为了简单起见,我们将使用 ping.exe 和 -t 参数。
ping -t google.com
我们希望能够 fork ping.exe 进程,以便 c# 应用程序可以尽快恢复执行,并且此示例中的 ping.exe 继续以愉快的方式继续执行。
我尝试在 powershell 脚本中运行 Start-Process,但这仍然会阻止 C# 应用程序的执行,直到所有进程都完全执行(因此它最终会运行到完成):
Start-Process ping -ArgumentList "-t","google.com" -RedirectStandardOutput ".\out.log" -RedirectStandardError ".\err.log"
我也尝试运行 Start-Job 并将启动过程包装在单独的作业中,但是,这似乎启动了作业,但从未完成
Start-Job -ScriptBlock { Start-Process ping -ArgumentList "-t","google.com" -RedirectStandardOutput ".\out.log" -RedirectStandardError ".\err.log" }
有什么方法可以在 PowerShell 中启动新进程并允许 C# 应用程序继续执行?
【问题讨论】:
-
既然可以do it directly,为什么还要从PowerShell运行
ping.exe? -
Ping 只是一个例子,我们在 PowerShell 脚本中启动了其他进程,但不希望它阻塞
-
但是你为什么要运行 PowerShell?只需生成您要运行的可执行文件。
-
就像我在问题中所说,我们无权访问运行 PowerShell 代码的 C# 应用程序,我们所拥有的只是可以运行的 PowerShell 脚本。
-
Start-Process异步运行一个进程。如果 C# 程序仍然阻塞,那么它一定是在等待由 PowerShell 进程启动的进程。
标签: c# powershell process start-job start-process