Run exe with an input file and close upon process exit

8 次查看(过去 30 天)
Hi,
I am creating a GUI where the user is to input parameters, MATLAB then creates an input file (exp.in) that is to be read into an exe. Once the cfd computations have completed, I would like the exe to close itself (if it is successful). I have the following created using similar queries by others however do not know how to go about passing the exe an input file.
proc = System.Diagnostics.Process();
proc.StartInfo.FileName = 'P:\path...cfd.exe';
%proc.StartInfo.Arguments = 'P:\path...exp.in';
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardInput = true;
proc.Start();
StreamWriter = proc.StandardInput;
sIn.AutoFlush = true;
sIn.write("dir P:\path...exp.in")
sIn.write("exit")
sIn.Close()
if isempty(proc)
error('Failed to launch process');
end
while true
if proc.HasExited
fprintf('\nProcess exited with status %d\n', proc.ExitCode);
break
end
fprintf('.');
pause(1.0);
end
Is there a way to pass on an input file for the exe to use. I have tried to use arguments but it doesn't work. Research suggests controlling process input via streamwriter.
I can use the system command to do so but then don't know how to close the exe once it finishes (have used taskkill to no avail; it closes before the process finishes).
Thanks in advance!
  4 个评论
Guillaume
Guillaume 2018-9-3
"in a more conventional way"
Not that conventional. There's a big difference between:
C:\> cfd.exe -i inputfile.in
which pass the name of a file to the executable and leave it up to the executable to read the file
and
C:\> cfd.exe < inputfile.in &
which tells the command prompt to read the inputfile and redirect its content to the executable (which would normally take its input from the keyboard). No argument is actually passed to the executable.
By the way, I'm not sure what that final & is by the way, as far as I know it's not legal or has no effect on its own.
As far as I can tell, the .Net code you show replicate that streaming process so if there's a problem you need to clarify what it actually is. Perhaps, what you write to the input stream is not correct.
As for, "With the above I get the error 'Struct contents reference from a non-struct array object.'". Of course, as documented status is numeric, not a structure. I've no idea where you picked up
if status.HasExited
it's not going to work since as said status is numeric (either 0 or 1) and additionally, does not get updated once you've received its value.
Anyway, the way to pass arguments to your executable and the way to terminate it once it's done what you need is going to depend entirely on the way that executable is designed. Hence you need to read its documentation and explain to us how that works, or if its documentation is available publicly give us a link.
Muhammad Munib
Muhammad Munib 2018-9-3
Sorry I meant that most of the answers given along with documentation use
system(cfd.exe < inputfile.in &')
With the &, it runs in its own command window, as I would like it to; without, it runs in the Matlab command window which I don't want. User should be able to see the computations and wait for them to complete.
The exe normally takes its input from the keyboard as you have stated and with '<' it accepts values sequentially. Beyond that it was written in Fortran, I would not know how it works, sorry. I've just been given the exe and am trying to create a GUI around it so users have something prettier to use than the command window as input.
The .Net code is from a similar query in Matlab Answers. I have tried to pass it arguments using
proc.StartInfo.Arguments = 'C:\inputFile.in';
to no avail. The rest of the code, as written in the original post works as I would like. So apart from the fact that it doesn't seem to read arguments (which may explain why with '-i' doesn't read the input, I think, I may be wrong) or I can't give it an input file to read using the stream writer, it closes after I manually enter inputs upon
if proc.HasExited
once the computations have finished.
Could I use
task = 'cfd.exe < inputfile.in'
[status, result] = system('cfd.exe < inputfile.in &');
and then write a while loop to identify when task has finished or would I have to gets its process ID.
Thanks. Appreciate any help.

请先登录,再进行评论。

采纳的回答

Guillaume
Guillaume 2018-9-3
As I said in my comment, cfd.exe < inputfile.in does not pass any input argument to the executable. It's a completely different mechanism, and proc.StartInfo.Arguments = 'C:\inputFile.in'; is not equivalent to that at all. The .Net equivalent would be
proc.Start;
streamreader = System.IO.StreamReader('C:\inputfile.in');
proc.StandardInput.Write(streamreader.ReadToEnd);
With regards to &, I was too focused on the windows side and forgot that it's a matlab argument to mean that system should return immediately without waiting for the process to finish. So, if you want matlab to continue only when the process has finished then don't include that final &.
As to killing the process, if I understood correctly, you shouldn't have to do that as your program accepts a quit command that will tells it to terminate. It's a lot cleaner than killing it.
  3 个评论
Guillaume
Guillaume 2018-9-5
This new problem has nothing to do with the .Net code. StandardInput is not a file, and your fopen, fprintf, etc. don't write to it anyway.
Most likely the problem is that you're missing
fclose(fileID);
at the end of your code. If your code is a function, the best way to ensure that the file is closed regardless of what happens (terminates successfully or errors) is to use
fileID =fopen(... %whatever the fopen code is
cleanupobj = onCleanup(@() fclose(fileID));
%when cleanupobj gets destroyed, either because the function exits normally
%or the function errors, fclose will be called
%... rest of code
Muhammad Munib
Muhammad Munib 2018-9-11
I've got it to work, I hadn't closed the stream reader so the fopen could not actually write anything to the file. Thank you for your help, much appreciated.
streamreader.close()

请先登录,再进行评论。

更多回答(1 个)

Fangjun Jiang
Fangjun Jiang 2018-8-14
Try to run system() manually first or open a command window and then type in line by line
cfd.exe <exp.in
exit
  1 个评论
Muhammad Munib
Muhammad Munib 2018-9-3
Sorry don't quite understand the steps.
Can I write something to exit the exe command window once it finishes its operations.
Thanks.

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 File Operations 的更多信息

产品


版本

R2017a

Community Treasure Hunt

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

Start Hunting!

Translated by