Re: [Mono-dev] System.Diagnostics.Process behaves differently in and outside of a NUnit test case
Hi Dan, As I am currently working on the Process class, I am getting a look at your bug. Does setting StandardOutputEncoding = Console.OutputEncoding on the ProcessStartInfo passed to Start fixes your issue? This is the behaviour on .NET, so this is the behaviour that we are going to adopt (at least for bug compatibility). Thank you! :) Ludovic -- Forwarded message - From: Dan LiewDate: Fri, 9 Oct 2015, 14:40 Subject: [Mono-dev] System.Diagnostics.Process behaves differently in and outside of a NUnit test case To: Hi, This is an issue that I was bitten by a while ago but I didn't post here because I managed to work around it but it looks like something inside mono changed between 3.12 and 4.0.4 which my broke my workaround. The issue basically is I observed my code failing when called from an NUnit test but when run from an executable it would work fine. The code in question [1] calls out to an external process using ``System.Diagnostics.Process`` where the standard input is redirected. When running from an NUnit test a UTF-8 BOM gets sent to the process's standard input and when running from an executable the UTF-8 BOM does not get sent. I looked at this again and I've noticed two things * In System.Diagnostics.Process.Start_noshell() the encoding for the writable end of the pipe connected to the child process's standard input is taken from ``Console.Out.Encoding``. Is this really a good idea? Depending on this global value seems like a bad idea and could introduce weird race conditions if the Console.Out encoding is changed in some way (e.g. ``Console.OutputEncoding = new System.Text.UTF8Encoding(false);`` seems to do this and this the new workaround I ended up using) * When running in an executable the value of ``Console.Out.Encoding.emitUTF8Identifier`` is false but when running in an NUnit test the value of Console.Out.Encoding.emitUTF8Identifier`` is true! I'm not sure if this is Mono's or NUnit's fault but this seems very wrong to me. I've filled a bug at [2] and [3] but thought I'd post about it here too as this issue seems partially tied to some of mono's internal implementation details. [1] https://bugzilla.xamarin.com/attachment.cgi?id=13247 [2] https://bugzilla.xamarin.com/show_bug.cgi?id=21374 [3] https://github.com/nunit/nunit/issues/881 Thanks, Dan. ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] System.Diagnostics.Process behaves differently in and outside of a NUnit test case
Hi Ludovic, On 15 October 2015 at 12:47, Ludovic Henrywrote: > Hi Dan, > > As I am currently working on the Process class, I am getting a look at your > bug. Thanks for taking a look :) > > Does setting StandardOutputEncoding = Console.OutputEncoding on the > ProcessStartInfo passed to Start fixes your issue? This is the behaviour on > .NET, so this is the behaviour that we are going to adopt (at least for bug > compatibility). For the version of mono I'm currently using (4.0.4) doing this doesn't work ``` StartInfo = new ProcessStartInfo(PathToSolverExecutable); StartInfo.Arguments = solverArguments; StartInfo.RedirectStandardInput = true; // Neccessary so we can send our query StartInfo.RedirectStandardOutput = true; // Necessary so we can read the output StartInfo.RedirectStandardError = true; StartInfo.UseShellExecute = false; // C# docs say this is required // This is a HACK TheEncoding = new System.Text.UTF8Encoding(/* encoderShouldEmitUTF8Identifier=*/ false); StartInfo.StandardOutputEncoding = TheEncoding; ``` The standard input stream is still sending the UTF-8 BOM. But doing this before creating the process works. ``` Console.OutputEncoding = new System.Text.UTF8Encoding(/* encoderShouldEmitUTF8Identifier=*/ false); ``` The only reason I knew to do this is because I looked at the implementation of ``System.Diagnostics.Process`` on my system and saw that this the encoding that is being used comes from ``Console.Out.Encoding`` and took a guess that if I modified ``Console.OutputEncoding`` the change "might" propagate to ``Console.Out.Encoding``. Here's the implementation code I was looking at. ``` if (startInfo.RedirectStandardInput == true) { MonoIO.Close (stdin_rd, out error); process.input_stream = new StreamWriter (new MonoSyncFileStream (stdin_wr, FileAccess.Write, true, 8192), Console.Out.Encoding); process.input_stream.AutoFlush = true; } ``` However I've noticed that the code in the master branch of mono is different. At a glance it looks like it's using ``startInfo.StandardOutputEncoding`` if it's not null ``` if (startInfo.RedirectStandardOutput) { MonoIO.Close (stdout_write, out error); Encoding stdoutEncoding = startInfo.StandardOutputEncoding ?? Console.Out.Encoding; process.output_stream = new StreamReader (new FileStream (new SafeFileHandle (stdout_read, false), FileAccess.Read, 8192, false), stdoutEncoding, true, 8192); } ``` So it looks like a nicer workaround is now available (I've not tested it though). It's a bit of a pain though as I can't rely on it in older versions of mono which means I have to use my horrible hack anyway :( Please note that the bug I filled about NUnit [1] has had a response. It sounds like NUnit is deliberately changing the encoding on standard output because they expect that it being redirected to a file. [1] https://github.com/nunit/nunit/issues/881 ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
[Mono-dev] System.Diagnostics.Process behaves differently in and outside of a NUnit test case
Hi, This is an issue that I was bitten by a while ago but I didn't post here because I managed to work around it but it looks like something inside mono changed between 3.12 and 4.0.4 which my broke my workaround. The issue basically is I observed my code failing when called from an NUnit test but when run from an executable it would work fine. The code in question [1] calls out to an external process using ``System.Diagnostics.Process`` where the standard input is redirected. When running from an NUnit test a UTF-8 BOM gets sent to the process's standard input and when running from an executable the UTF-8 BOM does not get sent. I looked at this again and I've noticed two things * In System.Diagnostics.Process.Start_noshell() the encoding for the writable end of the pipe connected to the child process's standard input is taken from ``Console.Out.Encoding``. Is this really a good idea? Depending on this global value seems like a bad idea and could introduce weird race conditions if the Console.Out encoding is changed in some way (e.g. ``Console.OutputEncoding = new System.Text.UTF8Encoding(false);`` seems to do this and this the new workaround I ended up using) * When running in an executable the value of ``Console.Out.Encoding.emitUTF8Identifier`` is false but when running in an NUnit test the value of Console.Out.Encoding.emitUTF8Identifier`` is true! I'm not sure if this is Mono's or NUnit's fault but this seems very wrong to me. I've filled a bug at [2] and [3] but thought I'd post about it here too as this issue seems partially tied to some of mono's internal implementation details. [1] https://bugzilla.xamarin.com/attachment.cgi?id=13247 [2] https://bugzilla.xamarin.com/show_bug.cgi?id=21374 [3] https://github.com/nunit/nunit/issues/881 Thanks, Dan. ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list