2

I know similar questions are overflowing this website (pun intended), but I cannot find get this to work without closing the .bat file I'm running. I'm sorry that I'm not very skillful at this, but any help is seriously appreciated.

What works:

// Start the child process.
Process p = new Process();
// Redirect the output stream of the child process.
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = @"C:\Temp\batch.bat";            
p.Start();          
string output = p.StandardOutput.ReadToEnd();

string DataDate =(output.Substring(output.LastIndexOf("echo date:") + 11));
string DataID1 =(output.Substring(output.LastIndexOf("echo id1:") + 10));
string DataID2 =(output.Substring(output.LastIndexOf("echo id2:") + 10));
string DataStatus =(output.Substring(output.LastIndexOf("echo status:") + 13));

This here opens a batch.bat file, which prints several lines that I can get to strings, such as: "echo date: 15.02.2019" goes to string DataDate. But I would like to open a command prompt and type new values myself without the command prompt closing. I'm using a button to run that code above. I think I to open the cmd process and store it every time there is a new line? How can I keep process alive and update my strings with newer values? For example I could type in the cmd prompt "echo date: 18.02.2019" and then that value would be saved.

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Automation
  • 23
  • 3

1 Answers1

1

If I understand your intention correctly you want an interaction with your process. Thus, your process must support this interaction. For example, you batch file may prompt commands and look like this:

@echo off

:loop
echo Enter a command:
set /p userCommand=""
%userCommand%
goto :loop

You can't use p.StandardOutput.ReadToEnd() since the output stream will not be finished yet until the output will be finished. You can use OutputDataReceived to perform asynchronous read. Try this code with the batch commands above:

Process process = new Process();
process.StartInfo.FileName = @"C:\Temp\batch.bat";
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.UseShellExecute = false;
process.OutputDataReceived += new DataReceivedEventHandler((sender, e) =>
{
    // Prepend line numbers to each line of the output.
    if (!String.IsNullOrEmpty(e.Data))
    {
        Console.WriteLine(e.Data);// to see what happens
        // parse e.Data here
    }
});

process.Start();

// Asynchronously read the standard output of the spawned process. 
// This raises OutputDataReceived events for each line of output.
process.BeginOutputReadLine();

process.WaitForExit();
process.Close();

Update

For Windows Forms app to make it work you need to change in VS Project Properties -> Application -> Output Type from Windows Application to Console Application. Or you can do it by editing *.csproj file and replacing <OutputType>WinExe</OutputType> by <OutputType>Exe</OutputType>. A a consequence of this, the console will be displayed during all app run time which maybe undesired for you. Honestly, I don't know how to make it in other way.

AlbertK
  • 11,841
  • 5
  • 40
  • 36
  • Thank you for your helpful response. That is exactly what I'm trying to do. I made the batch file like you said, and it looks perfect for testing. Unfortunately I'm having an issue that ends up crashing the program. I'm using iX Developer program to create this, which might cause its own problems. If I comment these two lines then the program won't crash. But I don't think I'm getting any information out if I do that. //process.StartInfo.RedirectStandardOutput = true; //process.BeginOutputReadLine(); – Automation Feb 19 '19 at 07:28
  • updated the answer. Added `process.StartInfo.UseShellExecute = false;`. It should fix the issue – AlbertK Feb 19 '19 at 08:14
  • Nice.. closer! But now the cmd.exe opens, but it's not doing anything. I mean the batch loop is not running, I cannot type any echoes in. – Automation Feb 19 '19 at 11:12
  • This code works fine in a simple console application. Check it and then try to see what are the differences between this code and code in your application – AlbertK Feb 19 '19 at 15:55
  • Interesting.. It DOES work very well with a console application. But the same cmd-just-idling-thing happens in a Windows Forms App. I must be doing something wrong there. I did manage to bypass the problem by using console application, and writing the incoming lines to a .txt file, and using the final program to read that file. It's not.. what I wanted, but it works, thanks to your help. Could you give me a hint why I have problems using it with the Windows Forms app? Perhaps I'm calling it all wrong.. But anyway! Thank you for your help! – Automation Feb 21 '19 at 08:20