Click here to Skip to main content
15,945,119 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I am trying to Use Process.Start() to automate executing an exe file.

I will first elaborate how to execute the exe file manually:

first, load the exe file by double click it, and after loading, the terminal will show entry info as follows, and the last line, the string 'udec>' is the place to type in commands (please ignore the Chinese characters due to my OS).

Shell
--- module2d plugin DFNModule2D loaded.
--- module2d plugin GeometryModule2D loaded.
--- module2d plugin Convert loaded.



                            U D E C: VERSION 7.00
               赏屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯突
               ?     Universal Distinct Element Code       ?
               掏屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯凸
               ?Copyright (c):Itasca Consulting Group 2017 ?
               ?                                           ?
               韧屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯图
                Licensee:      Itasca Consulting Group, Inc.
                               Minneapolis, Minnesota  USA
                Options:
                               Barton-Bandis
                               Creep
                               CppUdm
                               Flow
                               Thermal


                Memory:          4096 MBytes
                Precision:     Double
udec>


then I will type in command call 'D:\Work\202205\20220525\tunnel-for-cmd.txt' to execute it, and the result is as follows:

Shell
udec>call 'D:\Work\202205\20220525\tunnel-for-cmd.txt'

 ................
 ................
 calculation results
 ................
 ................


What I have tried:

What I am trying is to automate this activity, I use while loop and read from StandardOutput by int v = p.StandardOutput.Read();, and if v == 62 (which means I reached the end of the output, the '>' character), I will then write my command line to standard input. and my code is as follows:  
C#
try
            {
                var psi = new ProcessStartInfo()
                {
                    UseShellExecute = false,
                    FileName = @"D:\Program Files\ITASCA\UDEC700\Exe64\udecConsole2017.exe",
                    //Arguments = @"call 'D:\Work\202205\20220525\tunnel-for-cmd.txt'",
                    RedirectStandardInput = true,
                    RedirectStandardOutput = true,
                    CreateNoWindow = true,
                };
                var p = System.Diagnostics.Process.Start(psi);
                // Read until the udec> prompt
                while (true)
                {
                    //var line = p.StandardOutput.ReadLine();
                    //if (line.StartsWith("udec>"))
                    //    break;
                    int v = p.StandardOutput.Read();
                    Console.Write((char)v);
                    if (v == 62)
                    {
                        break;
                    }
                    if (v == -1)
                        break;
                }

                // Write the command
                Console.Write(@"call 'D:\Work\202205\20220525\tunnel-for-cmd.txt'");
                p.StandardInput.WriteLine(@"call 'D:\Work\202205\20220525\tunnel-for-cmd.txt'");
                p.StandardInput.Flush();

                // Read the result
                string content = p.StandardOutput.ReadToEnd();

                p.WaitForExit();
                Console.WriteLine(content);
               
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }


If I run the above code, I will get the starting infomation as expected (shown in the first snippet). Howerver, my simulation of "call 'D:\Work\202205\20220525\tunnel-for-cmd.txt'" fails. Although p.StandardInput.WriteLine() can be executed, when code runs after line 44 (string content = p.StandardOutput.ReadToEnd();), the program got hang up and deadlocked, and does not response so that I can only kill this progam.

I am not sure how to solve it.
Posted
Updated 30-Jun-22 12:43pm
v2
Comments
PIEBALDconsult 30-Jun-22 18:39pm    
Like this?

http://www.codeproject.com/Messages/3409061/How-do-I-drive-a-command-line-utility-beyond-execu.aspx

Shameful plug:

ProcessCommunicator[^]
 
Share this answer
 
You cannot use ReadToEnd on a console stream. What you think the "end" should be is not what ReadToEnd is looking at.

It is not hung or deadlocked. It's looking for an end that will never exist so long as your launched console process is running. The end comes at the termination of the process, NOT the end of the text coming from that process.

You have to use Read, much like you do for looking for the command prompt. Though, in that case, you're looking for a specific character when you should be looking for the entire prompt string.
 
Share this answer
 
Process.StandardOutput is just a StreamReader: Process.StandardOutput Property (System.Diagnostics) | Microsoft Docs[^] so ReadToEnd will wait for the end of output - which will you will only get when the application at the other end closes:
Quote:
ReadToEnd assumes that the stream knows when it has reached an end. For interactive protocols in which the server sends data only when you ask for it and does not close the connection, ReadToEnd might block indefinitely because it does not reach an end, and should be avoided.

Instead, you probably need to use a more normal Read operation and monitor exactly what the app is doing to find when to feed it commands.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900