[英]Process won't exit when UseShellExecute = false, but exits when UseShellExecute = true
I run a process from a asp.net core application:我从 asp.net 核心应用程序运行一个进程:
bool createShell = true;
//generate output pdf
using var pdfGeneratorProcess = new System.Diagnostics.Process
{
StartInfo = new ProcessStartInfo
{
UseShellExecute = createShell,
CreateNoWindow = createShell,
RedirectStandardError = !createShell,
RedirectStandardOutput = !createShell,
WorkingDirectory = dir,
FileName = "java",
Arguments = $"-cp \"fop-2.0.jar;lib/*\"; FOPLocalPDFGenerator {rendererFile} {inputFile} {outputFile}"
}
};
_logger.LogInformation("{CMD}", $"{pdfGeneratorProcess.StartInfo.FileName} {pdfGeneratorProcess.StartInfo.Arguments}");
pdfGeneratorProcess.Start();
When createShell is true, the process writes some PDF file and exits.当 createShell 为真时,进程写入一些 PDF 文件并退出。 When I set it to false, it runs with the same StandardOutput and StandardError it seems, but never finishes and the PDF file is empty.当我将其设置为 false 时,它会以相同的 StandardOutput 和 StandardError 运行,但从未完成,并且 PDF 文件为空。
Why does the process hang when there is no console window visible?为什么没有控制台 window 可见时进程挂起?
When ProcessStartInfo.RedirectStandardOutput is true, the process's output is redirected to Process.StandardOutput .当ProcessStartInfo.RedirectStandardOutput为真时,进程的 output 被重定向到Process.StandardOutput 。
But in the OP code the Process.StandardOutput
isn't read and the buffer fills up to its limit.但是在 OP 代码中,没有读取Process.StandardOutput
并且缓冲区填满了它的限制。 When the limit is reached, the process can't write Process.StandardOutput
and wait some free space.当达到限制时,进程无法写入Process.StandardOutput
并等待一些可用空间。
Same story with ProcessStartInfo.RedirectStandardError and Process.StandardError ProcessStartInfo.RedirectStandardError和Process.StandardError的故事相同
One solution is to set ProcessStartInfo.RedirectStandardOutput
and ProcessStartInfo.RedirectStandardError
to false.一种解决方案是将ProcessStartInfo.RedirectStandardOutput
和ProcessStartInfo.RedirectStandardError
设置为 false。
Other solution if you want the output, you can redirect the output to other stream.其他解决方案如果您想要 output,您可以将 output 重定向到其他 stream。 See this example where the output is redirected to a file:请参阅此示例,其中 output 被重定向到文件:
void Redirect(StreamReader output, StreamWriter to)
{
string textLine;
while ((textLine = output.ReadLine()) != null)
{
to.WriteLine(textLine);
}
}
bool createShell = true;
//generate output pdf
using var pdfGeneratorProcess = new System.Diagnostics.Process {
StartInfo = new ProcessStartInfo {
UseShellExecute = createShell,
CreateNoWindow = !createShell, // I inversed the condition
RedirectStandardError = !createShell,
RedirectStandardOutput = !createShell,
WorkingDirectory = dir,
FileName = "java",
Arguments = $"-cp \"fop-2.0.jar;lib/*\"; FOPLocalPDFGenerator {rendererFile} {inputFile} {outputFile}"
}
};
_logger.LogInformation("{CMD}", $"{pdfGeneratorProcess.StartInfo.FileName} {pdfGeneratorProcess.StartInfo.Arguments}");
pdfGeneratorProcess.Start();
using (StreamWriter writer = File.CreateText(@"C:\Temp\log.txt"))
{
var standardOutputThread = new Thread(new ThreadStart(() => Redirect(pdfGeneratorProcess.StandardOutput, writer)));
var errorOutputThread = new Thread(new ThreadStart(() => Redirect(pdfGeneratorProcess.StandardError, writer)));
standardOutputThread.Start();
errorOutputThread.Start();
standardOutputThread.Join();
errorOutputThread.Join();
}
pdfGeneratorProcess.WaitForExit();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.