Ejemplo n.º 1
0
        public static string ExecuteForStandardOutput(ChildProcessStartInfo si, Encoding?encoding = null)
        {
            using var p = ChildProcess.Start(si);

            if (p.HasStandardInput)
            {
                p.StandardInput.Close();
            }

            if (p.HasStandardError)
            {
                p.StandardError.Close();
            }

            using var sr = new StreamReader(p.StandardOutput, encoding ?? Encoding.UTF8);
            var standardOutput = sr.ReadToEnd();

            p.WaitForExit();

            if (p.ExitCode != 0)
            {
                throw new ChildProcessFailedException($"Child process failed with exit code {p.ExitCode} (0x{p.ExitCode:X8}).");
            }

            return(standardOutput);
        }
Ejemplo n.º 2
0
        public void ConnectsInputPipe()
        {
            using var tmp = new TemporaryDirectory();
            var outFile = Path.Combine(tmp.Location, "out");

            var si = new ChildProcessStartInfo(TestUtil.DotnetCommandName, TestUtil.TestChildPath, "EchoBack")
            {
                StdInputRedirection  = InputRedirection.InputPipe,
                StdOutputRedirection = OutputRedirection.File,
                StdOutputFile        = outFile,
                StdErrorRedirection  = OutputRedirection.NullDevice,
            };

            using var sut = ChildProcess.Start(si);
            const string Text = "foo";

            using (var sw = new StreamWriter(sut.StandardInput))
            {
                sw.Write(Text);
            }
            sut.WaitForExit();

            Assert.True(sut.HasStandardInput);
            Assert.False(sut.HasStandardOutput);
            Assert.False(sut.HasStandardError);
            Assert.Equal(Text, File.ReadAllText(outFile));
        }
Ejemplo n.º 3
0
        public void RedirectionToNull()
        {
            {
                var si = new ChildProcessStartInfo(TestUtil.DotnetCommandName, TestUtil.TestChildPath, "EchoBack")
                {
                    StdInputRedirection  = InputRedirection.NullDevice,
                    StdOutputRedirection = OutputRedirection.NullDevice,
                    StdErrorRedirection  = OutputRedirection.NullDevice,
                };

                using var sut = ChildProcess.Start(si);
                sut.WaitForExit();
                Assert.Equal(0, sut.ExitCode);
            }

            {
                var si = new ChildProcessStartInfo(TestUtil.DotnetCommandName, TestUtil.TestChildPath, "EchoOutAndError")
                {
                    StdInputRedirection  = InputRedirection.NullDevice,
                    StdOutputRedirection = OutputRedirection.NullDevice,
                    StdErrorRedirection  = OutputRedirection.NullDevice,
                };

                using var sut = ChildProcess.Start(si);
                sut.WaitForExit();
                Assert.Equal(0, sut.ExitCode);
            }
        }
        public void CanObtainExitCode()
        {
            {
                var si = new ChildProcessStartInfo(
                    TestUtil.DotnetCommandName,
                    TestUtil.TestChildPath,
                    "ExitCode",
                    "0");

                using var sut = ChildProcess.Start(si);
                sut.WaitForExit();
                Assert.Equal(0, sut.ExitCode);
            }

            {
                // An exit code is 32-bit on Windows while it is 8-bit on POSIX.
                int nonZeroExitCode = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? unchecked ((int)0xc0000005) : 255;

                var si = new ChildProcessStartInfo(
                    TestUtil.DotnetCommandName,
                    TestUtil.TestChildPath,
                    "ExitCode",
                    nonZeroExitCode.ToString(CultureInfo.InvariantCulture));

                using var sut = ChildProcess.Start(si);
                sut.WaitForExit();
                Assert.NotEqual(0, sut.ExitCode);
                Assert.Equal(nonZeroExitCode, sut.ExitCode);
            }
        }
        public void CanSendSignal()
        {
            var si = new ChildProcessStartInfo(TestUtil.TestChildNativePath, "ReportSignal")
            {
                StdInputRedirection = InputRedirection.InputPipe,
                StdOutputRedirection = OutputRedirection.OutputPipe,
            };

            using var sut = ChildProcess.Start(si);

            Assert.True(sut.CanSignal);

            Assert.Equal('R', sut.StandardOutput.ReadByte());

            sut.SignalInterrupt();
            Assert.Equal('I', sut.StandardOutput.ReadByte());

            sut.SignalInterrupt();
            Assert.Equal('I', sut.StandardOutput.ReadByte());

            if (!HasWorkaroundForWindows1809)
            {
                // NOTE: On Windows, a console app cannot cancel CTRL_CLOSE_EVENT (generated when the attached pseudo console is closed).
                //       It will be killed after the 5s-timeout elapses. Once we call SignalTermination, we must treat the app as already terminated.
                //       https://docs.microsoft.com/en-us/windows/console/handlerroutine#timeouts
                sut.SignalTermination();
                Assert.Equal('T', sut.StandardOutput.ReadByte());
            }

            sut.Kill();
            sut.WaitForExit();

            Assert.NotEqual(0, sut.ExitCode);
        }
        private static ChildProcessImpl CreateForWaitForExitTest()
        {
            var si = new ChildProcessStartInfo(TestUtil.DotnetCommandName, TestUtil.TestChildPath, "EchoBack")
            {
                StdInputRedirection  = InputRedirection.InputPipe,
                StdOutputRedirection = OutputRedirection.NullDevice,
                StdErrorRedirection  = OutputRedirection.NullDevice,
            };

            return((ChildProcessImpl)ChildProcess.Start(si));
        }
Ejemplo n.º 7
0
        public void ChildProcessWaitForAsyncIsTrulyAsynchronous()
        {
            var si = new ChildProcessStartInfo(TestUtil.DotnetCommandName, TestUtil.TestChildPath, "Sleep", "1000")
            {
                StdOutputRedirection = OutputRedirection.NullDevice,
                StdErrorRedirection  = OutputRedirection.NullDevice,
            };

            using var sut = ChildProcess.Start(si);
            WaitForAsyncIsTrulyAsynchronous(sut);
            sut.WaitForExit();
            Assert.Equal(0, sut.ExitCode);
        }
        public void ExitCodeThrowsBeforeChildExits()
        {
            var si = new ChildProcessStartInfo(TestUtil.DotnetCommandName, TestUtil.TestChildPath, "EchoBack")
            {
                StdInputRedirection = InputRedirection.InputPipe,
            };

            using var sut = ChildProcess.Start(si);
            Assert.Throws <InvalidOperationException>(() => sut.ExitCode);

            sut.StandardInput.Close();
            sut.WaitForExit();

            Assert.Equal(0, sut.ExitCode);
        }
Ejemplo n.º 9
0
        public void StreamPropertiesThrowWhenNoPipeAssociated()
        {
            var si = new ChildProcessStartInfo(TestUtil.DotnetCommandName, TestUtil.TestChildPath, "ExitCode", "0")
            {
                StdInputRedirection  = InputRedirection.NullDevice,
                StdOutputRedirection = OutputRedirection.NullDevice,
                StdErrorRedirection  = OutputRedirection.NullDevice,
            };

            using var sut = ChildProcess.Start(si);

            Assert.False(sut.HasStandardInput);
            Assert.False(sut.HasStandardOutput);
            Assert.False(sut.HasStandardError);
            Assert.Throws <InvalidOperationException>(() => sut.StandardInput);
            Assert.Throws <InvalidOperationException>(() => sut.StandardOutput);
            Assert.Throws <InvalidOperationException>(() => sut.StandardError);

            sut.WaitForExit();
        }
Ejemplo n.º 10
0
        public void ConnectsErrorPipe()
        {
            var si = new ChildProcessStartInfo(TestUtil.DotnetCommandName, TestUtil.TestChildPath, "EchoOutAndError")
            {
                StdInputRedirection  = InputRedirection.NullDevice,
                StdOutputRedirection = OutputRedirection.NullDevice,
                StdErrorRedirection  = OutputRedirection.ErrorPipe,
            };

            using var sut = ChildProcess.Start(si);
            using var sr  = new StreamReader(sut.StandardError);
            var output = sr.ReadToEnd();

            sut.WaitForExit();

            Assert.False(sut.HasStandardInput);
            Assert.False(sut.HasStandardOutput);
            Assert.True(sut.HasStandardError);
            Assert.Equal(0, sut.ExitCode);
            Assert.Equal("TestChild.Error", output);
        }
        public void CannotSendSignalIfAttachedToCurrentConsole()
        {
            var si = new ChildProcessStartInfo(TestUtil.TestChildNativePath, "ReportSignal")
            {
                StdInputRedirection = InputRedirection.InputPipe,
                StdOutputRedirection = OutputRedirection.OutputPipe,
                Flags = ChildProcessFlags.AttachToCurrentConsole,
            };

            using var sut = ChildProcess.Start(si);

            Assert.False(sut.CanSignal);
            Assert.Throws<InvalidOperationException>(() => sut.SignalInterrupt());
            Assert.Throws<InvalidOperationException>(() => sut.SignalTermination());
            Assert.Equal('R', sut.StandardOutput.ReadByte());

            sut.Kill();
            sut.WaitForExit();

            Assert.NotEqual(0, sut.ExitCode);
        }
Ejemplo n.º 12
0
        public async Task ConnectOutputAndErrorPipes()
        {
            {
                var si = new ChildProcessStartInfo(TestUtil.DotnetCommandName, TestUtil.TestChildPath, "EchoOutAndError")
                {
                    StdOutputRedirection = OutputRedirection.OutputPipe,
                    StdErrorRedirection  = OutputRedirection.ErrorPipe,
                };

                using var sut = ChildProcess.Start(si);
                await Impl(sut, "TestChild.Out", "TestChild.Error");
            }

            {
                // invert stdout and stderr
                var si = new ChildProcessStartInfo(TestUtil.DotnetCommandName, TestUtil.TestChildPath, "EchoOutAndError")
                {
                    StdOutputRedirection = OutputRedirection.ErrorPipe,
                    StdErrorRedirection  = OutputRedirection.OutputPipe,
                };

                using var sut = ChildProcess.Start(si);
                await Impl(sut, "TestChild.Error", "TestChild.Out");
            }
Ejemplo n.º 13
0
        private static IChildProcess CreateProcessTree(AnonymousPipeServerStream stdOutputPipe)
        {
            var si = new ChildProcessStartInfo(
                TestUtil.DotnetCommandName,
                TestUtil.TestChildPath,
                "SpawnAndWait",
                TestUtil.DotnetCommandName,
                TestUtil.TestChildPath,
                "EchoAndSleepAndEcho",
                "S",
                SleepMilliseconds,
                "Exited")
            {
                StdInputRedirection  = InputRedirection.NullDevice,
                StdOutputRedirection = OutputRedirection.Handle,
                StdOutputHandle      = stdOutputPipe.ClientSafePipeHandle,
                StdErrorRedirection  = OutputRedirection.NullDevice,
            };

            var p = ChildProcess.Start(si);

            try
            {
                stdOutputPipe.DisposeLocalCopyOfClientHandle();

                // Wait for the grand child to echo.
                Assert.Equal((byte)'S', stdOutputPipe.ReadByte());
            }
            catch
            {
                p.Dispose();
                throw;
            }

            return(p);
        }
Ejemplo n.º 14
0
        public void RejectsInvalidRedirection()
        {
            using var tmp = new TemporaryDirectory();
            var filePath = Path.Combine(tmp.Location, "file");

            // null
            Assert.Throws <ArgumentException>(() => ChildProcess.Start(
                                                  new ChildProcessStartInfo(TestUtil.TestChildNativePath)
            {
                StdInputRedirection = InputRedirection.Handle
            }));
            Assert.Throws <ArgumentException>(() => ChildProcess.Start(
                                                  new ChildProcessStartInfo(TestUtil.TestChildNativePath)
            {
                StdInputRedirection = InputRedirection.File
            }));
            Assert.Throws <ArgumentException>(() => ChildProcess.Start(
                                                  new ChildProcessStartInfo(TestUtil.TestChildNativePath)
            {
                StdOutputRedirection = OutputRedirection.Handle
            }));
            Assert.Throws <ArgumentException>(() => ChildProcess.Start(
                                                  new ChildProcessStartInfo(TestUtil.TestChildNativePath)
            {
                StdOutputRedirection = OutputRedirection.File
            }));
            Assert.Throws <ArgumentException>(() => ChildProcess.Start(
                                                  new ChildProcessStartInfo(TestUtil.TestChildNativePath)
            {
                StdOutputRedirection = OutputRedirection.AppendToFile
            }));
            Assert.Throws <ArgumentException>(() => ChildProcess.Start(
                                                  new ChildProcessStartInfo(TestUtil.TestChildNativePath)
            {
                StdErrorRedirection = OutputRedirection.Handle
            }));
            Assert.Throws <ArgumentException>(() => ChildProcess.Start(
                                                  new ChildProcessStartInfo(TestUtil.TestChildNativePath)
            {
                StdErrorRedirection = OutputRedirection.File
            }));
            Assert.Throws <ArgumentException>(() => ChildProcess.Start(
                                                  new ChildProcessStartInfo(TestUtil.TestChildNativePath)
            {
                StdErrorRedirection = OutputRedirection.AppendToFile
            }));

            // Enum value out of range
            Assert.Throws <ArgumentOutOfRangeException>(() => ChildProcess.Start(
                                                            new ChildProcessStartInfo(TestUtil.TestChildNativePath)
            {
                StdInputRedirection = (InputRedirection)(-1)
            }));
            Assert.Throws <ArgumentOutOfRangeException>(() => ChildProcess.Start(
                                                            new ChildProcessStartInfo(TestUtil.TestChildNativePath)
            {
                StdOutputRedirection = (OutputRedirection)(-1)
            }));
            Assert.Throws <ArgumentOutOfRangeException>(() => ChildProcess.Start(
                                                            new ChildProcessStartInfo(TestUtil.TestChildNativePath)
            {
                StdErrorRedirection = (OutputRedirection)(-1)
            }));

            // When both stdout and stderr are redirected to the same file, they must have the same "append" option.
            Assert.Throws <ArgumentException>(() => ChildProcess.Start(
                                                  new ChildProcessStartInfo(TestUtil.TestChildNativePath)
            {
                StdOutputFile        = filePath,
                StdOutputRedirection = OutputRedirection.File,
                StdErrorFile         = filePath,
                StdErrorRedirection  = OutputRedirection.AppendToFile,
            }));
            Assert.Throws <ArgumentException>(() => ChildProcess.Start(
                                                  new ChildProcessStartInfo(TestUtil.TestChildNativePath)
            {
                StdOutputFile        = filePath,
                StdOutputRedirection = OutputRedirection.AppendToFile,
                StdErrorFile         = filePath,
                StdErrorRedirection  = OutputRedirection.File,
            }));
        }