0

In Console Application, Windows 10, Visual Studio 2015, .NET 4.6 i call single method in Main called TestProcess. Build mode Debug, if I run app without debugging it prints correct text:

827ccb0eea8a706c4c34a16891f84e7b *test.txt

Press any key to continue . . .

If i run app with debugging it waits for 3 seconds before printing

Error False False False '' ''

This is just simplification of real problem, this code is backbone of some complex code which also hangs in release without debugging for md5sums.exe, but works for some other programs. Coplex code also also hangs on var a = proc.WaitForExit(timeout); until timeout as in attached example. On the other hand this simplification will work in release without debugger. Also, all this problems started with Windows 10, on Windows 7 it all worked fine.

[EDIT] Can't understand why would md5sums.exe cause problems, and if I use something else ie. FileName = "ping", Arguments = "localhost" everything works as expected.

[EDIT2] My complex program stopped working on Windows 10 (Release - Run without debugging), but this example hangs on Windows 7 also (Debug - Run with debugging)

        static void TestProcess()
        {
            using (var proc = new Process())
            {
                proc.StartInfo.FileName = "md5sums.exe";
                proc.StartInfo.WorkingDirectory = @"C:\Temp\ProcessDebug";
                proc.StartInfo.Arguments = "-u test.txt";
                proc.StartInfo.CreateNoWindow = true;
                proc.StartInfo.UseShellExecute = false;
                proc.StartInfo.RedirectStandardOutput = true;
                proc.StartInfo.RedirectStandardError = true;
                StringBuilder output = new StringBuilder();
                StringBuilder error = new StringBuilder();
                using (AutoResetEvent outputWaitHandle = new AutoResetEvent(false))
                using (AutoResetEvent errorWaitHandle = new AutoResetEvent(false))
                {
                    proc.OutputDataReceived += (sender, e) =>
                    {
                        if (e.Data == null)
                            outputWaitHandle.Set();
                        else
                            output.AppendLine(e.Data);
                    };
                    proc.ErrorDataReceived += (sender, e) =>
                    {
                        if (e.Data == null)
                            errorWaitHandle.Set();
                        else
                            error.AppendLine(e.Data);
                    };
                    proc.Start();
                    proc.BeginOutputReadLine();
                    proc.BeginErrorReadLine();
                    var timeout = 1000;
                    var a = proc.WaitForExit(timeout);
                    var b = outputWaitHandle.WaitOne(timeout);
                    var c = errorWaitHandle.WaitOne(timeout);
                    if (a && b && c)
                        Console.WriteLine(output.ToString());
                    else
                        Console.WriteLine($"Error {a} {b} {c} '{output}' '{error}'");
                }
            }
        }
watbywbarif
  • 6,487
  • 8
  • 50
  • 64
  • This problem has a very simple solution. You can only ever discover it when you write a *meaningful* error message, one that gives the user of your program a good hint what exactly went wrong. A good rule of thumb is not never use a timeout less than 10 seconds on a workstation PC, 20 seconds on a server. Add more if it is a "complex" program. – Hans Passant May 17 '16 at 14:01
  • @HansPassant Complex program has timeout in days :) 20 sec timeout didn't change behaviour for this example, although test.txt is file with just one short line of text and Console.WriteLine($"Error: '{error.ToString()}', '{output.ToString()}'"); returned |"Error: '', ''|. a,b and c are all false when it fails. What would meaningful error message be? – watbywbarif May 17 '16 at 14:29
  • 1
    @watbywbarif try to disable the VS Hosting Process and see what happens. https://msdn.microsoft.com/en-us/library/ms185330.aspx – Mihail Shishkov May 18 '16 at 06:43
  • 1
    Also comment out the ErrorDataReceived part and check again. You are setting the errorWaitHandle only if an "error" is ever received. What happens if ErrorDataReceived event is never fired? The errorWaitHandle will timeout. – Mihail Shishkov May 18 '16 at 06:46
  • @MihailShishkov Thanks for good suggestions. CS Hosting changed nothing, neither did commenting, it fails on all waits: a,b and c. – watbywbarif May 18 '16 at 07:31
  • 1
    Here is some code that can help you in your situation. http://stackoverflow.com/questions/21848271/redirecting-standard-input-of-console-application/21848564#21848564 – Mihail Shishkov May 18 '16 at 11:10
  • @MihailShishkov Thanks, for now i will keep using old code as problem looks solved now by simple switch for md5sums. But inconsistent behavior of programs like this is very strange to me. Who knows what other skeletons will come back to me with windows 10. – watbywbarif May 18 '16 at 11:20

1 Answers1

1

There were 3 catches to solve this:

  • md5sums.exe in some cases pauses execution after finished when launched with my settings:

827ccb0eea8a706c4c34a16891f84e7b *test.txt

Press ENTER to exit

This can be observed if CreateNoWindow is set to false and stdout, stderr redirection removed. This can be fixed by using -e switch: 'Exit immediately; don't pause before returning'. This will fix all cases. But as i didn't use -e i had inconsistent behavior depending on debugger and windows version.

  • When running without debugging pause was not fired although all settings were same, and "Press ENTER to exit" was not in output. But running with debugging caused pause to block program until timeout, where md5sums would hang in task manager waiting for Enter.
  • In release mode, run without debugging, although pause fired and "Press ENTER to exit" was in output on Windows 7 md5sums returned and execution continued without blocking and hitting timeout. This was not case on Windows 10 where md5sums would live in task manger waiting for Enter and program continued after hitting timeout.
watbywbarif
  • 6,487
  • 8
  • 50
  • 64