ProcessInfo and RedirectStandardOutput
I've experienced this before. Sometimes, the way in which the process you're calling outputs to the console is not compatible with this sort of output redirection. I've been fortunate enough in this case to be able to modify the external process to get around this.
You might try running your code on another process that outputs to the console, and see if it works properly. It reads about right to me right now.
EDIT:
I went and pulled a code block I've used to do this. This is in a WPF app which redirects the process output to the window. Notice the event binding. Since this is WPF I have to invoke my call to write the data out. Since you aren't worried about blocking, ou should be able to simply replace that with:
Console.WriteLine(e.Data);
Hopefully it helps!
private static void LaunchProcess()
{
Process build = new Process();
build.StartInfo.WorkingDirectory = @"dir";
build.StartInfo.Arguments = "";
build.StartInfo.FileName = "my.exe";
build.StartInfo.UseShellExecute = false;
build.StartInfo.RedirectStandardOutput = true;
build.StartInfo.RedirectStandardError = true;
build.StartInfo.CreateNoWindow = true;
build.ErrorDataReceived += build_ErrorDataReceived;
build.OutputDataReceived += build_ErrorDataReceived;
build.EnableRaisingEvents = true;
build.Start();
build.BeginOutputReadLine();
build.BeginErrorReadLine();
build.WaitForExit();
}
// write out info to the display window
static void build_ErrorDataReceived(object sender, DataReceivedEventArgs e)
{
string strMessage = e.Data;
if (richTextBox != null && !String.Empty(strMessage))
{
App.Instance.Dispatcher.BeginInvoke(DispatcherPriority.Send, (ThreadStart)delegate()
{
Paragraph para = new Paragraph(new Run(strMessage));
para.Margin = new Thickness(0);
para.Background = brushErrorBrush;
box.Document.Blocks.Add(para);
});
}
}
Workaround mutually exclusive UseShellExecute and RedirectStandardOutput
I don't see why you want to set UseShellExecute
to true. It needs to be false to allow redirection of the standard IO channels
If the location of the perl compiler executable is in PATH then you can just set FileName
to perl
. It's also better to use String.Format
to build strings out of variables rather than use all those escaped quotes and concatenations
Dim myProcess As New System.Diagnostics.Process
myProcess.StartInfo.WorkingDirectory = "K:\Engineering\Temp\perl"
myProcess.StartInfo.UseShellExecute = False
myProcess.StartInfo.FileName = "perl"
myProcess.StartInfo.Arguments = String.Format(
"perlcompare.pl ""{0}"" ""{1}"" ""{2}""",
MasterFile,
MasterOutput,
ComparisonsOutput)
myProcess.StartInfo.RedirectStandardOutput = True
myProcess.Start()
If the location of the perl compiler isn't in the PATH then you can just put a fully-qualified file path into FileName
Redirect a process's output to both a file and the console
Could use something like that
using System;
using System.Diagnostics;
namespace InteractWithConsoleApp
{
class Program
{
static void Main(string[] args)
{
ProcessStartInfo cmdStartInfo = new ProcessStartInfo();
cmdStartInfo.FileName = @"C:\Windows\System32\cmd.exe";
cmdStartInfo.RedirectStandardOutput = true;
cmdStartInfo.RedirectStandardError = true;
cmdStartInfo.RedirectStandardInput = true;
cmdStartInfo.UseShellExecute = false;
cmdStartInfo.CreateNoWindow = true;
Process cmdProcess = new Process();
cmdProcess.StartInfo = cmdStartInfo;
cmdProcess.ErrorDataReceived += cmd_Error;
cmdProcess.OutputDataReceived += cmd_DataReceived;
cmdProcess.EnableRaisingEvents = true;
cmdProcess.Start();
cmdProcess.BeginOutputReadLine();
cmdProcess.BeginErrorReadLine();
cmdProcess.StandardInput.WriteLine("ping google.com.ua"); //Execute ping google.com.ua
cmdProcess.StandardInput.WriteLine("exit"); //Execute exit.
cmdProcess.WaitForExit();
}
static void cmd_DataReceived(object sender, DataReceivedEventArgs e)
{
Console.WriteLine("Output from other process");
Console.WriteLine(e.Data);
}
static void cmd_Error(object sender, DataReceivedEventArgs e)
{
Console.WriteLine("Error from other process");
Console.WriteLine(e.Data);
}
}
}
Redirect standard output and prompt for UAC with ProcessStartInfo
UseShellExecute
must be set to false
to redirect IO, and to true
to use the Verb
property. So you can't.
But this article seems do the magic, although I haven't tested it.
It's written in C++, but a wrapper API can easily be created to be called from C# by using DllImport
.
Note: If you want to pass data between the two programs and have access to the target program's source code, you can easily re-design you application to use Named Pipes
instead of redirecting standard I/O.
Related Topics
How to Find One Image Inside of Another
Only Parameterless Constructors and Initializers Are Supported in Linq to Entities
How to Initialize a C# Attribute with an Array or Other Variable Number of Arguments
Controlling Execution Order of Unit Tests in Visual Studio
How to Display the Displayattribute.Description Attribute Value
Should I Abstract the Validation Framework from Domain Layer
@Html.Hiddenfor Does Not Work on Lists in ASP.NET MVC
Async Implementation of Ivalueconverter
Set Cultureinfo in ASP.NET Core to Have a . as Currencydecimalseparator Instead of ,
How to Use a Controller in Another Assembly in ASP.NET Core MVC 2.0
Does ASP.NET MVC Have Application Variables
Fields of Class, Are They Stored in the Stack or Heap
Entity Framework Code First Lazy Loading
Sharing Data Between Appdomains
Accordion in Windows Forms Datagridview
How to Get a List of Keys from JSON.Net
Linq to Entities Doesn't Recognize a Method
How Does Entity Framework Work with Recursive Hierarchies? Include() Seems Not to Work with It