Reputation: 75
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
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
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