How to redirect standard input and standard output using .Net System.Diagnostics.Process
You are now following this question
- You will see updates in your followed content feed.
- You may receive emails, depending on your communication preferences.
An Error Occurred
Unable to complete the action because of changes made to the page. Reload the page to see its updated state.
Show older comments
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.
1 Comment
Mohammad Sami
on 31 Aug 2020
Edited: Walter Roberson
on 2 Sep 2020
Accepted Answer
Mohammad Sami
on 31 Aug 2020
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
Michael Maurice
on 1 Sep 2020
Edited: Michael Maurice
on 1 Sep 2020
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.
You might need to flush the buffer.
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);
Michael Maurice
on 2 Sep 2020
Edited: Michael Maurice
on 2 Sep 2020
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.
Michael Maurice
on 2 Sep 2020
Edited: Michael Maurice
on 2 Sep 2020
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()
Mohammad Sami
on 2 Sep 2020
Good to know it's working for you and the final solution.
More Answers (0)
Categories
Find more on Gas Dynamics in Help Center and File Exchange
See Also
on 31 Aug 2020
on 2 Sep 2020
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)