I’m developing a C# application and I need to start an external console program to perform some tasks (extract files). What I need to do is to redirect the output of the console program. Code like this one does not work, because it raises events only when a new line is writen in the console program, but the one I use “updates” what’s shown in the console window, without writting any new lines. How can I raise an event every time the text in the console is updated? Or just get the output of the console program every X seconds? Thanks in advance!
Share
I have had a very similar (possibly the exact) problem as you describe:
What I ended up doing goes like this:
StandardOutput.BaseStream.BeginRead.BeginRead, check if the return value ofEndReadis0; this means that the console process has closed its output stream (i.e. will never write anything to standard output again).BeginReadforces you to use a constant-length buffer, check if the return value ofEndReadis equal to the buffer size. This means that there may be more output waiting to be read, and it may be desirable (or even necessary) that this output is processed all in one piece. What I did was keep aStringBuilderaround and append the output read so far. Whenever output is read but its length is < the buffer length, notify yourself (I do it with an event) that there is output, send the contents of theStringBuilderto the subscriber, and then clear it.However, in my case I was simply writing more stuff to the console’s standard output. I ‘m not sure what “updating” the output means in your case.
Update: I just realized (isn’t explaining what you are doing a great learning experience?) that the logic outlined above has an off-by-one bug: If the length of the output read by
BeginReadis exactly equal to the length of your buffer, then this logic will store the output in theStringBuilderand block while trying to see if there’s more output to append. The “current” output will only be sent back to you when/if more output is available, as part of a larger string.Obviously some method of guarding against this (or a biggish buffer plus faith in your powers of luck) is needed to do this 100% correctly.
Update 2 (code):
DISCLAIMER:
This code is not production-ready. It is the result of me quickly hacking together a proof of concept solution to do what needed to be done. Please do not use it as it stands in your production application. If this code causes horrible things to happen to you, I will pretend someone else wrote it.
Used like so: