Open
Description
Description
When using output redirection, along with the start command, WaitForExit()
does not properly detect the exit.
See the following code:
process.StartInfo = new ProcessStartInfo()
{
FileName = "cmd.exe",
Arguments = "/C " + $"\"start cmd /c \"echo test && timeout /t 3\"\"",
UseShellExecute = false,
RedirectStandardError = true,
RedirectStandardOutput = true,
CreateNoWindow = true
};
process.OutputDataReceived += ProcessOnOutputDataReceived;
process.ErrorDataReceived += ProcessOnErrorDataReceived;
_stopwatch.Start();
Console.WriteLine("Starting process...");
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
process.WaitForExit();
Console.WriteLine($"Process exited: {_stopwatch.ElapsedMilliseconds}");
Console.ReadLine();
The output is as follows:
Starting process...
OUT (3062): NULL
ERR (3062): NULL
Process exited: 3062
You can see that it waits for the second 3 second cmd process finishes, even though it should return immediately after the original cmd.exe exits.
However, if either a timeout is provided to WaitForExit
, or redirection is not enabled, it will return as expected:
process.WaitForExit(60000);
Output:
Starting process...
Process exited: 26
ERR (3171): NULL
OUT (3171): NULL
Note that the output still does not return null until the second cmd process exits.
Reproduction Steps
public static void Run()
{
var process = new Process();
process.StartInfo = new ProcessStartInfo()
{
FileName = "cmd.exe",
Arguments = "/C " + $"\"start cmd /c \"echo test && timeout /t 3\"\"",
UseShellExecute = false,
RedirectStandardError = true,
RedirectStandardOutput = true,
CreateNoWindow = true
};
process.OutputDataReceived += ProcessOnOutputDataReceived;
process.ErrorDataReceived += ProcessOnErrorDataReceived;
var stopwatch = new Stopwatch();
stopwatch.Start();
Console.WriteLine("Starting process...");
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
process.WaitForExit();
Console.WriteLine($"Process exited: {stopwatch.ElapsedMilliseconds}");
Console.ReadLine();
}
private static void ProcessOnErrorDataReceived(object sender, DataReceivedEventArgs e)
{
Console.WriteLine("ERR: " + (e.Data ?? "NULL"));
}
private static void ProcessOnOutputDataReceived(object sender, DataReceivedEventArgs e)
{
Console.WriteLine("OUT: " + (e.Data ?? "NULL"));
}
Expected behavior
WaitForExit()
should return once the first cmd process exits, and likewise OutputDataReceived/ErrorDataReceived should send null.
Configuration
Windows 11 x64
.NET 8.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment