Reputation: 27328
I run a process from a asp.net core application:
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. 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.
Why does the process hang when there is no console window visible?
Upvotes: 0
Views: 1011
Reputation: 7590
When ProcessStartInfo.RedirectStandardOutput is true, the process's output is redirected to Process.StandardOutput.
But in the OP code the Process.StandardOutput
isn't read and the buffer fills up to its limit. When the limit is reached, the process can't write Process.StandardOutput
and wait some free space.
Same story with ProcessStartInfo.RedirectStandardError and Process.StandardError
One solution is to set ProcessStartInfo.RedirectStandardOutput
and ProcessStartInfo.RedirectStandardError
to false.
Other solution if you want the output, you can redirect the output to other stream. See this example where the output is redirected to a file :
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();
Upvotes: 0