public async Task CorrectlyConnectOutputPipes() { { var si = new ChildProcessStartInfo(TestUtil.DotnetCommand, TestUtil.TestChildPath, "EchoOutAndError") { StdOutputRedirection = OutputRedirection.OutputPipe, StdErrorRedirection = OutputRedirection.ErrorPipe, }; using (var sut = ChildProcess.Start(si)) { await ChildProcessAssert.CorrectlyConnectsPipesAsync(sut, "TestChild.Out", "TestChild.Error"); } } { // invert stdout and stderr var si = new ChildProcessStartInfo(TestUtil.DotnetCommand, TestUtil.TestChildPath, "EchoOutAndError") { StdOutputRedirection = OutputRedirection.ErrorPipe, StdErrorRedirection = OutputRedirection.OutputPipe, }; using (var sut = ChildProcess.Start(si)) { await ChildProcessAssert.CorrectlyConnectsPipesAsync(sut, "TestChild.Error", "TestChild.Out"); } } }
/// <summary> /// Starts a child process as specified in <paramref name="startInfo"/>. /// </summary> /// <param name="startInfo"><see cref="ChildProcessStartInfo"/>.</param> /// <returns>The started process.</returns> /// <exception cref="IOException">Failed to open a specified file.</exception> /// <exception cref="ProcessCreationFailedException">Process creation failed.</exception> public static ChildProcess Start(ChildProcessStartInfo startInfo) { startInfo = startInfo ?? throw new ArgumentNullException(nameof(startInfo)); using (var stdHandles = new PipelineStdHandleCreator(startInfo)) { var processHandle = ProcessPal.SpawnProcess( fileName: startInfo.FileName, arguments: startInfo.Arguments, workingDirectory: startInfo.WorkingDirectory, environmentVariables: startInfo.EnvironmentVariables, stdIn: stdHandles.PipelineStdIn, stdOut: stdHandles.PipelineStdOut, stdErr: stdHandles.PipelineStdErr); try { var process = new ChildProcess(processHandle, stdHandles.InputStream, stdHandles.OutputStream, stdHandles.ErrorStream); stdHandles.DetachStreams(); return(process); } catch { processHandle.Dispose(); throw; } } }
public async Task PipesAreAsynchronous() { var si = new ChildProcessStartInfo(TestUtil.DotnetCommand, TestUtil.TestChildPath, "EchoBack") { StdInputRedirection = InputRedirection.InputPipe, StdOutputRedirection = OutputRedirection.OutputPipe, StdErrorRedirection = OutputRedirection.ErrorPipe, }; using (var sut = ChildProcess.Start(si)) { Assert.True(((FileStream)sut.StandardInput).IsAsync); Assert.True(((FileStream)sut.StandardOutput).IsAsync); Assert.True(((FileStream)sut.StandardError).IsAsync); using (var sr = new StreamReader(sut.StandardOutput)) { const string text = "foobar"; var stdoutTask = sr.ReadToEndAsync(); using (var sw = new StreamWriter(sut.StandardInput)) { await sw.WriteAsync(text); } Assert.Equal(text, await stdoutTask); } sut.WaitForExit(); Assert.Equal(0, sut.ExitCode); } }
public void RedirectionToHandle() { using (var tmp = new TemporaryDirectory()) { var inFile = Path.Combine(tmp.Location, "in"); var outFile = Path.Combine(tmp.Location, "out"); var errFile = Path.Combine(tmp.Location, "err"); // StdOutputHandle StdErrorHandle { using (var fsOut = File.Create(outFile)) using (var fsErr = File.Create(errFile)) { // File var si = new ChildProcessStartInfo(TestUtil.DotnetCommand, TestUtil.TestChildPath, "EchoOutAndError") { StdOutputRedirection = OutputRedirection.Handle, StdOutputHandle = fsOut.SafeFileHandle, StdErrorRedirection = OutputRedirection.Handle, StdErrorHandle = fsErr.SafeFileHandle, }; using (var sut = ChildProcess.Start(si)) { sut.WaitForExit(); Assert.True(sut.IsSuccessful); } } Assert.Equal("TestChild.Out", File.ReadAllText(outFile)); Assert.Equal("TestChild.Error", File.ReadAllText(errFile)); } // StdInputHandle { const string text = "foobar"; File.WriteAllText(inFile, text); using (var fsIn = File.OpenRead(inFile)) { var si = new ChildProcessStartInfo(TestUtil.DotnetCommand, TestUtil.TestChildPath, "EchoBack") { StdInputRedirection = InputRedirection.Handle, StdInputHandle = fsIn.SafeFileHandle, StdOutputRedirection = OutputRedirection.File, StdOutputFile = outFile, }; using (var sut = ChildProcess.Start(si)) { sut.WaitForExit(); Assert.True(sut.IsSuccessful); } } Assert.Equal(text, File.ReadAllText(outFile)); } } }
private static ChildProcess CreateForWaitForExitTest() { var si = new ChildProcessStartInfo(TestUtil.DotnetCommand, TestUtil.TestChildPath, "EchoBack") { StdInputRedirection = InputRedirection.InputPipe, StdOutputRedirection = OutputRedirection.NullDevice, }; return(ChildProcess.Start(si)); }
public void CanCreateChildProcess() { var si = new ChildProcessStartInfo(TestUtil.DotnetCommand, TestUtil.TestChildPath) { StdOutputRedirection = OutputRedirection.OutputPipe, }; using (var sut = ChildProcess.Start(si)) { ChildProcessAssert.CanCreateChildProcess(sut); } }
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.True(sut.IsSuccessful); }
public void ChildProcessWaitForAsyncIsTrulyAsynchronous() { var si = new ChildProcessStartInfo(TestUtil.TestChildPath, "Sleep", "1000") { StdOutputRedirection = OutputRedirection.NullDevice, StdErrorRedirection = OutputRedirection.NullDevice, }; using (var sut = ChildProcess.Start(si)) { WaitForAsyncIsTrulyAsynchronous(sut); } }
public async Task PipesAreAsynchronous() { var si = new ChildProcessStartInfo(TestUtil.DotnetCommand, TestUtil.TestChildPath, "EchoBack") { StdInputRedirection = InputRedirection.InputPipe, StdOutputRedirection = OutputRedirection.OutputPipe, StdErrorRedirection = OutputRedirection.ErrorPipe, }; using (var sut = ChildProcess.Start(si)) { await ChildProcessAssert.PipesAreAsynchronousAsync(sut); } }
public void CanCreateChildProcess() { var si = new ChildProcessStartInfo(TestUtil.DotnetCommandName, TestUtil.TestChildPath) { StdOutputRedirection = OutputRedirection.OutputPipe, }; using var sut = ChildProcess.Start(si); sut.WaitForExit(); Assert.Equal(0, sut.ExitCode); // This closes StandardOutput, which should be acceptable. using var sr = new StreamReader(sut.StandardOutput !); Assert.Equal("TestChild", sr.ReadToEnd()); }
public void CanRedirectToSameFile() { using (var tmp = new TemporaryDirectory()) { var outFile = Path.Combine(tmp.Location, "out"); // StdOutputFile StdErrorFile { // File var si = new ChildProcessStartInfo(TestUtil.DotnetCommand, TestUtil.TestChildPath, "EchoOutAndError") { StdOutputRedirection = OutputRedirection.File, StdOutputFile = outFile, StdErrorRedirection = OutputRedirection.File, StdErrorFile = outFile, }; using (var sut = ChildProcess.Start(si)) { sut.WaitForExit(); Assert.True(sut.IsSuccessful); } Assert.Equal("TestChild.OutTestChild.Error", File.ReadAllText(outFile)); // AppendToFile si = new ChildProcessStartInfo(TestUtil.DotnetCommand, TestUtil.TestChildPath, "EchoOutAndError") { StdOutputRedirection = OutputRedirection.AppendToFile, StdOutputFile = outFile, StdErrorRedirection = OutputRedirection.AppendToFile, StdErrorFile = outFile, }; using (var sut = ChildProcess.Start(si)) { sut.WaitForExit(); Assert.True(sut.IsSuccessful); } Assert.Equal("TestChild.OutTestChild.ErrorTestChild.OutTestChild.Error", File.ReadAllText(outFile)); } } }
public void ExitCodeThrowsBeforeChildExits() { var si = new ChildProcessStartInfo(TestUtil.DotnetCommand, TestUtil.TestChildPath, "EchoBack") { StdInputRedirection = InputRedirection.InputPipe, }; using (var sut = ChildProcess.Start(si)) { Assert.Throws <InvalidOperationException>(() => sut.IsSuccessful); Assert.Throws <InvalidOperationException>(() => sut.ExitCode); sut.StandardInput.Close(); sut.WaitForExit(); Assert.True(sut.IsSuccessful); Assert.Equal(0, sut.ExitCode); } }
public void CanObtainExitCode() { { var si = new ChildProcessStartInfo(TestUtil.DotnetCommand, TestUtil.TestChildPath, "ExitCode", "0"); using (var sut = ChildProcess.Start(si)) { sut.WaitForExit(); Assert.True(sut.IsSuccessful); Assert.Equal(0, sut.ExitCode); } } { var si = new ChildProcessStartInfo(TestUtil.DotnetCommand, TestUtil.TestChildPath, "ExitCode", "-1"); using (var sut = ChildProcess.Start(si)) { sut.WaitForExit(); Assert.False(sut.IsSuccessful); Assert.Equal(-1, sut.ExitCode); } } }
public void ReportsCreationFailure() { var si = new ChildProcessStartInfo("nonexistentfile"); Assert.Throws <ProcessCreationFailedException>(() => ChildProcess.Start(si)); }
public void RedirectionToFile() { using (var tmp = new TemporaryDirectory()) { var inFile = Path.Combine(tmp.Location, "in"); var outFile = Path.Combine(tmp.Location, "out"); var errFile = Path.Combine(tmp.Location, "err"); // StdOutputFile StdErrorFile { // File var si = new ChildProcessStartInfo(TestUtil.TestChildPath, "EchoOutAndError") { StdOutputRedirection = OutputRedirection.File, StdOutputFile = outFile, StdErrorRedirection = OutputRedirection.File, StdErrorFile = errFile, }; using (var sut = ChildProcess.Start(si)) { sut.WaitForExit(); Assert.True(sut.IsSuccessful); } Assert.Equal("TestChild.Out", File.ReadAllText(outFile)); Assert.Equal("TestChild.Error", File.ReadAllText(errFile)); // AppendToFile si = new ChildProcessStartInfo(TestUtil.TestChildPath, "EchoOutAndError") { StdOutputRedirection = OutputRedirection.AppendToFile, StdOutputFile = errFile, StdErrorRedirection = OutputRedirection.AppendToFile, StdErrorFile = outFile, }; using (var sut = ChildProcess.Start(si)) { sut.WaitForExit(); Assert.True(sut.IsSuccessful); } Assert.Equal("TestChild.OutTestChild.Error", File.ReadAllText(outFile)); Assert.Equal("TestChild.ErrorTestChild.Out", File.ReadAllText(errFile)); } // StdInputFile { const string text = "foobar"; File.WriteAllText(inFile, text); var si = new ChildProcessStartInfo(TestUtil.TestChildPath, "EchoBack") { StdInputRedirection = InputRedirection.File, StdInputFile = inFile, StdOutputRedirection = OutputRedirection.File, StdOutputFile = outFile, }; using (var sut = ChildProcess.Start(si)) { sut.WaitForExit(); Assert.True(sut.IsSuccessful); } Assert.Equal(text, File.ReadAllText(outFile)); } } }