Pipping data to and from process
-
What I need to do is something like this.
DataCruncher.exe < input.bin > output.bin
It is an application that is called in the command prompt. The input.bin file is piped in, and the result is outputed to output.bin. Works great. Now instead of starting the app from a command prompt, I need to call it from a C# app.ProcessStartInfo info = new ProcessStartInfo(location);
info.Arguments = BuildArgs();
info.RedirectStandardInput = true;
info.RedirectStandardOutput = true;
info.RedirectStandardError = true;
info.UseShellExecute = false;_process = Process.Start(info);
_toApp = _process.StandardInput.BaseStream;
_fromApp = _process.StandardOutput.BaseStream;The input is in binary format, and so is the output, so I used the basestream instead of the StreamReader. My problem is that it is blocking when im reading from the standard output.
while (true)
{
int read = _fromApp.Read(readbuffer, 0, readbuffer.Length); // <-- blocksif (read == 0)
break;//Do something with the data.
}It looks like it is blocking the stream until it has all the bytes to fill the readbuffer array. Is there something I should be aware of when read/writting to a process?
-
What I need to do is something like this.
DataCruncher.exe < input.bin > output.bin
It is an application that is called in the command prompt. The input.bin file is piped in, and the result is outputed to output.bin. Works great. Now instead of starting the app from a command prompt, I need to call it from a C# app.ProcessStartInfo info = new ProcessStartInfo(location);
info.Arguments = BuildArgs();
info.RedirectStandardInput = true;
info.RedirectStandardOutput = true;
info.RedirectStandardError = true;
info.UseShellExecute = false;_process = Process.Start(info);
_toApp = _process.StandardInput.BaseStream;
_fromApp = _process.StandardOutput.BaseStream;The input is in binary format, and so is the output, so I used the basestream instead of the StreamReader. My problem is that it is blocking when im reading from the standard output.
while (true)
{
int read = _fromApp.Read(readbuffer, 0, readbuffer.Length); // <-- blocksif (read == 0)
break;//Do something with the data.
}It looks like it is blocking the stream until it has all the bytes to fill the readbuffer array. Is there something I should be aware of when read/writting to a process?
Hi, the way I understand it, but this could be wrong, I don't have a reference to this, is this: - the process input and output are designed to be used for text; - the data is transferred from one process to the other on a line by line basis, and each full line is somehow guaranteed to become available in one go. So it's my guess you aren't getting any data because there aren't any newline characters in your binary data. You could experiment with binary data that happens to contain some \r or \n or \r\n sequences, to see whether that splits it in smaller parts. If so, seems like you should either abandon binary data, or choose another way of communicating (actual files, memory mapped files, ...) :)
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get. Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
-
Hi, the way I understand it, but this could be wrong, I don't have a reference to this, is this: - the process input and output are designed to be used for text; - the data is transferred from one process to the other on a line by line basis, and each full line is somehow guaranteed to become available in one go. So it's my guess you aren't getting any data because there aren't any newline characters in your binary data. You could experiment with binary data that happens to contain some \r or \n or \r\n sequences, to see whether that splits it in smaller parts. If so, seems like you should either abandon binary data, or choose another way of communicating (actual files, memory mapped files, ...) :)
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get. Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
-
Hi Thank you for your quick response. I did some more work on it, and it looks like it was a threading issue. If I read the out stream in a diferent thread, it does not block. Im not sure why, but it works.
Yeah, I couldn't tell the threading situation from the code you have shown; if you were performing the reads from the GUI thread (say in a button click handler), then all the GUI changes you ordered in there would not become effective until that handler (i.e. all reads) have finished (unless you added some extra calls such as Invalidate or Refresh). If you do use a separate thread, that one can't touch any Controls; you would need Control.Invoke for that. This[^] explains it. And finally, if your data were text, not binary, you could have used the OutputDataReceived event instead of a separate thread... :)
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get. Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
-
Yeah, I couldn't tell the threading situation from the code you have shown; if you were performing the reads from the GUI thread (say in a button click handler), then all the GUI changes you ordered in there would not become effective until that handler (i.e. all reads) have finished (unless you added some extra calls such as Invalidate or Refresh). If you do use a separate thread, that one can't touch any Controls; you would need Control.Invoke for that. This[^] explains it. And finally, if your data were text, not binary, you could have used the OutputDataReceived event instead of a separate thread... :)
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get. Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
Yeah, I look at the OutputDataReceived event, and for a moment considered doing reverse text encoding on the string - but that was an absolute last resort :D The threading is handled internally, and has no contact to the GUI. You can se a sample of it at: http://bendtsen.net/sample.txt[^]