BeingIan
BeingIan

Reputation: 75

C# Process not receiving inputs

I have a process that calls a fortran executable. The executable requests a file from the user and performs operations to find a solution. If multiple solutions are found on the file, the program will ask the user if they would like to find the most optimal solution, basically 2 inputs for the program. The executable then generates a text file that provide results of the program.

The process is able to run, however the resulting text file is not generated. Also when I checked for the output of the application, the message prompt ("Enter a file") is the only thing stored in the string and it doesn't include the secondary prompt for the optimal solution ("Would you like to find the most optimal solution?"). Can anyone give me an idea as to why this is happening? Thanks.

Process exeProcess = new Process();
exeProcess.StartInfo.FileName = "sdf45.exe";
exeProcess.StartInfo.UseShellExecute = false;
exeProcess.StartInfo.RedirectStandardError = true;
exeProcess.StartInfo.RedirectStandardInput = true;
exeProcess.StartInfo.RedirectStandardOutput = true;
exeProcess.Start();        
//input file                
exeProcess.StandardInput.WriteLine(Path.GetFileName(filePath));            
//find optimal solution
exeProcess.StandardInput.WriteLine("Y");
string output = exeProcess.StandardOutput.ReadToEnd();            
exeProcess.WaitForExit();

Upvotes: 3

Views: 604

Answers (2)

Chris Shain
Chris Shain

Reputation: 51329

My guess is that this line is executing (and returning) before the FORTRAN process even has a chance to read the input:

string output = exeProcess.StandardOutput.ReadToEnd();

I am not 100% sure what the result of ReadToEnd(); on an unbounded stream is in this case. The proper way to do this, as mentioned by Jon Skeet here, is to read from stdout in another thread or better yet asynchronously, as documented here: http://msdn.microsoft.com/en-us/library/system.diagnostics.process.beginoutputreadline.aspx

For posterity's sake a rough example:

var outputReader = new Thread(ReadOutput);
outputReader.Start(exeProcess);

where ReadOutput is defined something like this:

public void ReadOutput(Object processState) {
    var process = processState as Process;
    if (process == null) return;
    var output = exeProcess.StandardOutput.ReadToEnd();
    // Do whetever with output
}

Making your initial method:

Process exeProcess = new Process();
exeProcess.StartInfo.FileName = "sdf45.exe";
exeProcess.StartInfo.UseShellExecute = false;
exeProcess.StartInfo.RedirectStandardError = true;
exeProcess.StartInfo.RedirectStandardInput = true;
exeProcess.StartInfo.RedirectStandardOutput = true;
exeProcess.Start();        
//input file                
exeProcess.StandardInput.WriteLine(Path.GetFileName(filePath));            
//find optimal solution
exeProcess.StandardInput.WriteLine("Y");
var outputReader = new Thread(ReadOutput);
outputReader.Start(exeProcess);
exeProcess.WaitForExit();
outputReader.Join();

Upvotes: 1

Tigran
Tigran

Reputation: 62246

It's difficult to say, but I presume that you need to pass an arguments to the executable, like this

Process exeProcess = new Process();
exeProcess.StartInfo.FileName = "sdf45.exe";
exeProcess.StartInfo.UseShellExecute = false;
exeProcess.StartInfo.RedirectStandardError = true;
exeProcess.StartInfo.RedirectStandardInput = true;
exeProcess.StartInfo.RedirectStandardOutput = true;
exeProcess.StartInfo.Arguments = Path.GetFileName(filePath); //pass file path to EXE
exeProcess.Start();

Hope this helps

Upvotes: 0

Related Questions