简体   繁体   English

UseShellExecute = false 时进程不会退出,但 UseShellExecute = true 时退出

[英]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.RedirectStandardErrorProcess.StandardError的故事相同

One solution is to set ProcessStartInfo.RedirectStandardOutput and ProcessStartInfo.RedirectStandardError to false.一种解决方案是将ProcessStartInfo.RedirectStandardOutputProcessStartInfo.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.

相关问题 ProcessStartInfo.UseShellExecute = true并等待进程退出 - ProcessStartInfo.UseShellExecute = true and waiting for process exit 当 useshellexecute = false 时 Process.start 找不到文件 - Process.start does not find file when useshellexecute = false Ctrl + C即使UseShellExecute:false也不应关闭进程 - Ctrl + C should not close process even when UseShellExecute:false 当 UseShellExecute 为真时,如何读取控制台 output? - How to read console output when UseShellExecute is true? 当UseShellExecute == false时,如何在C#进程上强制输出标准输出? - How do I force standard output on a C# Process when UseShellExecute == false? 创建新的 .Net Core 控制台进程:使用具有 UseShellExecute=true 的环境变量时出现异常 - Creating new .Net Core Console Process: Exception when using environment variables with UseShellExecute=true 如何在没有'useshellexecute = false'的过程中进行读写 - How to write and read in a process without 'useshellexecute = false' 我们什么时候需要将 ProcessStartInfo.UseShellExecute 设置为 True? - When do we need to set ProcessStartInfo.UseShellExecute to True? 从服务挂起启动流程UseShellExecute false - Start Process from Service hung UseShellExecute false 提升权限不适用于UseShellExecute = false - Elevating privileges doesn't work with UseShellExecute=false
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM