从 C# 应用程序中托管的 powershell 中分离进程
Detaching process from powershell hosted in C# application
我们有一个执行 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 脚本,它有一个漫长的 运行ning 过程,为了简单起见,我们只使用 ping.exe
和 -t
参数。
ping -t google.com
我们希望能够 fork ping.exe
进程,以便 c# 应用程序可以尽快恢复执行,并且本示例中的 ping.exe
继续以其愉快的方式运行。
我已经尝试在 powershell 脚本中 运行 Start-Process
但这仍然只是阻止 C# 应用程序的执行,直到所有进程都完全执行(所以它最终 运行s 完成):
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# 应用程序继续执行?
我找到了一个解决方法 - 如果我将 -Verb Open
传递给 Start-Process
,它似乎会立即恢复对 C# 应用程序的执行。唯一的问题是您无法将标准输出或错误重定向到文件。
Start-Process ping -ArgumentList "-t","google.com" -Verb Open
我们有一个执行 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 脚本,它有一个漫长的 运行ning 过程,为了简单起见,我们只使用 ping.exe
和 -t
参数。
ping -t google.com
我们希望能够 fork ping.exe
进程,以便 c# 应用程序可以尽快恢复执行,并且本示例中的 ping.exe
继续以其愉快的方式运行。
我已经尝试在 powershell 脚本中 运行 Start-Process
但这仍然只是阻止 C# 应用程序的执行,直到所有进程都完全执行(所以它最终 运行s 完成):
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# 应用程序继续执行?
我找到了一个解决方法 - 如果我将 -Verb Open
传递给 Start-Process
,它似乎会立即恢复对 C# 应用程序的执行。唯一的问题是您无法将标准输出或错误重定向到文件。
Start-Process ping -ArgumentList "-t","google.com" -Verb Open