How to redirect standard input and standard output using .Net System.Dia​gnostics.P​rocess

I'm working on some optimisation code and have recently moved away from using the system() function to open xfoil.exe and direct input and output files,
cmd = sprintf('cd %s && xfoil.exe < xfoil.inp > xfoil.out &',working_directory);
[status,result] = system(cmd);
and I am now attempting to complete the same operations using:
process = System.Diagnostics.Process();
process.StartInfo.FileName = 'xfoil.exe';
process.StartInfo.Arguments = %not sure what to put here%;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.CreateNoWindow = false;
process.Start();
I'm not very experienced with coding in general, so I'm struggling a bit here, but I really need some help to figure out how to redirect standard input and standard output to my two files (xfoil.inp and xfoil.out) using .Net System.Diagnostics.Process.

 Accepted Answer

You can try this. You may have to choose the option on how to decide when xfoil.exe has finished reading.
process = System.Diagnostics.Process();
process.StartInfo.FileName = 'xfoil.exe';
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.CreateNoWindow = false;
process.Start();
stdin = process.StandardInput;
stdout = process.StandardOutput;
fid = fopen('xfoil.inp','r'); % read the xfoil.inp
txt = fread(fid,'*char');
fclose(fid);
stdin.Write(txt); % send the input to xfoil.exe
out = stdout.ReadToEndAsync;
% wait for xfoil.exe to finish processing
% option 1
pause(1); % pause for a predefined amount of time
% option 2
% wait until xfoil.exe has terminated
while(~process.HasExited)
pause(1);
end
try
process.Kill; % kill the process if needed.
catch
end
xfoil_out = char(out.Result);

10 Comments

Thanks for your help. This is definitely more on the right track. The code seems to work for the most part, and I'm able to print the xfoil output to "xfoil.out". The only weird issue I'm having now is xfoil is not completing its entire run. Based on the input file, "xfoil.inp", it should analyse across the range of angles 0 to 18 (for computational fluid dynamics analysis), however, it appears to stop at 17 degrees. This is weird, because using the old method of running xfoil (shown just below) didn't have any issues running from 0 to 18 and terminating using the same input file. I'm not sure why the new running process is getting hung up before finishing.
cmd = sprintf('cd %s && xfoil.exe < xfoil.inp > xfoil.out',wd);
% [status,result] = system(cmd);
This is the xfoil run function so far:
process = System.Diagnostics.Process();
process.StartInfo.FileName = 'xfoil.exe';
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.CreateNoWindow = false;
process.Start();
stdin = process.StandardInput;
stdout = process.StandardOutput;
%input data
fid_in = fopen('xfoil.inp','r'); % read the xfoil.inp
txt = fread(fid_in,'*char');
fclose(fid_in);
stdin.Write(txt); % send the input to xfoil.exe
out = stdout.ReadToEndAsync;
while(~process.HasExited)
pause(1);
end
%output data
xfoil_out = char(out.Result);
fid_out = fopen('xfoil.out','w');
fprintf(fid_out,xfoil_out);
fclose(fid_out);
The process mustn't be reaching the end of my input file, of which the last few lines inlclude:
alfa 18
dump xfoil_a18.000_dump.dat
cpwr xfoil_a18.000_cpwr.dat
pwrt
xfoil_pwrt.dat
plis
quit
Perhaps if you try to write the input one line at a time. Or try setting AutoFlush to true.
stdin = process.StandardInput;
%stdin.AutoFlush = true; % can also try adding autoflush to true
stdout = process.StandardOutput;
%input data
fid_in = fopen('xfoil.inp','r'); % read the xfoil.inp
while ~feof(fid)
tline = fgetl(fid_in);
disp(tline);
stdin.WriteLine(tline); % send the input to xfoil.exe
end
fclose(fid_in);
Ok, it appears that the entire input file is being read, however, the final lines are not being passed to xfoil.exe. This occurs even if I remove input text from the input file. The whole file is read, but stdin appears to not pass the last few lines into xfoil.exe.
This still wont pass the entire input file to xfoil.exe, even with "stdin.AutoFlush = true;" :
process = System.Diagnostics.Process();
process.StartInfo.FileName = 'xfoil.exe';
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.CreateNoWindow = true;
process.Start();
stdin = process.StandardInput;
stdin.AutoFlush = true;
stdout = process.StandardOutput;
% input data
fid_in = fopen('xfoil.inp','r'); % read the xfoil.inp
streamreader = System.IO.StreamReader('xfoil.inp');
stdin.Write(streamreader.ReadToEnd); % send the input to xfoil.exe
fclose(fid_in);
out = stdout.ReadToEndAsync;
Running the input process like this confirms that the input is being read properly, as the command window displays the complete input, but xfoil.exe still mustn't be receiving the entire input data, because it is not executing all the input commands. This is so frustrating.
%input data
fid_in = fopen('xfoil.inp','r'); % read the xfoil.inp
while ~feof(fid_in)
input = fgetl(fid_in);
disp(input)
stdin.WriteLine(input); % send the input to xfoil.exe
end
fclose(fid_in);
The input text looks like this:
load xy_new.txt
panels
n
330
oper
iter
1000
oper
re 1e+06
mach 0
visc
pacc
alfa 0
dump xfoil_a00.000_dump.dat
cpwr xfoil_a00.000_cpwr.dat
alfa 1
dump xfoil_a01.000_dump.dat
cpwr xfoil_a01.000_cpwr.dat
alfa 2
dump xfoil_a02.000_dump.dat
cpwr xfoil_a02.000_cpwr.dat
alfa 3
dump xfoil_a03.000_dump.dat
cpwr xfoil_a03.000_cpwr.dat
alfa 4
dump xfoil_a04.000_dump.dat
cpwr xfoil_a04.000_cpwr.dat
alfa 5
dump xfoil_a05.000_dump.dat
cpwr xfoil_a05.000_cpwr.dat
alfa 6
dump xfoil_a06.000_dump.dat
cpwr xfoil_a06.000_cpwr.dat
alfa 7
dump xfoil_a07.000_dump.dat
cpwr xfoil_a07.000_cpwr.dat
alfa 8
dump xfoil_a08.000_dump.dat
cpwr xfoil_a08.000_cpwr.dat
alfa 9
dump xfoil_a09.000_dump.dat
cpwr xfoil_a09.000_cpwr.dat
alfa 10
dump xfoil_a10.000_dump.dat
cpwr xfoil_a10.000_cpwr.dat
alfa 11
dump xfoil_a11.000_dump.dat
cpwr xfoil_a11.000_cpwr.dat
alfa 12
dump xfoil_a12.000_dump.dat
cpwr xfoil_a12.000_cpwr.dat
alfa 13
dump xfoil_a13.000_dump.dat
cpwr xfoil_a13.000_cpwr.dat
alfa 14
dump xfoil_a14.000_dump.dat
cpwr xfoil_a14.000_cpwr.dat
alfa 15
dump xfoil_a15.000_dump.dat
cpwr xfoil_a15.000_cpwr.dat
alfa 16
dump xfoil_a16.000_dump.dat
cpwr xfoil_a16.000_cpwr.dat
alfa 17
dump xfoil_a17.000_dump.dat
cpwr xfoil_a17.000_cpwr.dat
alfa 18
dump xfoil_a18.000_dump.dat
cpwr xfoil_a18.000_cpwr.dat
pwrt
xfoil_pwrt.dat
plis
quit
But for some reason, even if I delete some of the "alfa" iterations, xfoil.exe only reads up to the 2nd-last "alfa" iteration.
I think i got it! Standard input needs to be closed. I added "stdin.Close()'. This is the updated code, which is now delivering all input data from "xfoil.inp" to xfoil.exe:
%input data
fid_in = fopen('xfoil.inp','r'); % read the xfoil.inp
while ~feof(fid_in)
input = fgetl(fid_in);
disp(input)
stdin.WriteLine(input); % send the input to xfoil.exe
end
stdin.Close()
Good to know it's working for you and the final solution.

Sign in to comment.

More Answers (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!