Run exe with an input file and close upon process exit

8 visualizaciones (últimos 30 días)
Muhammad Munib
Muhammad Munib el 14 de Ag. de 2018
Comentada: Muhammad Munib el 11 de Sept. de 2018
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 comentarios
Guillaume
Guillaume el 3 de Sept. de 2018
"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 el 3 de Sept. de 2018
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.

Iniciar sesión para comentar.

Respuesta aceptada

Guillaume
Guillaume el 3 de Sept. de 2018
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 comentarios
Guillaume
Guillaume el 5 de Sept. de 2018
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 el 11 de Sept. de 2018
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()

Iniciar sesión para comentar.

Más respuestas (1)

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

Iniciar sesión para comentar.

Categorías

Más información sobre File Operations en Help Center y File Exchange.

Productos


Versión

R2017a

Community Treasure Hunt

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

Start Hunting!

Translated by