C # application for stdin / stdout console application

I have an interesting (reading: disappointing) issue starting a console application from a C # WPF application and redirecting its stdin and stdout.

It basically works and works, but I don't seem to get some data from stdout as soon as I start the stdin redirection.

I will explain an example. If I do not set hStdInput in the STARTUPINFO structure when I start the child process, I get the following:

MongoDB shell version: 2.2.0 connecting to: test local:PRIMARY> 

Once I installed hStdInput, I just get the following:

 MongoDB shell version: 2.2.0 connecting to: test 

I know that the stdout of processing BackgroundWorker is still functioning, because if I send something to the process on stdin, it responds accordingly.

 use TestDB switched to db TestDB 

So here is how I create the process:

 _processInfo = new ProcessInfo(); bool ok = false; SECURITY_ATTRIBUTES sattr = new SECURITY_ATTRIBUTES(); sattr.bInheritHandle = 1; unsafe { sattr.lpSecurityDescriptor = null; } sattr.nLength = Marshal.SizeOf(sattr); IntPtr hWrite; ok = CreatePipe(out _hReadStdOut, out hWrite, ref sattr, 0); ok = SetHandleInformation(_hReadStdOut, HANDLE_FLAGS.INHERIT, 0); IntPtr hRead; ok = CreatePipe(out hRead, out _hWriteStdIn, ref sattr, 0); ok = SetHandleInformation(_hWriteStdIn, HANDLE_FLAGS.INHERIT, 0); var startInfo = new StartupInfo { dwFlags = 0x0001 | 0x0100, wShowWindow = 0, hStdOutput = hWrite, hStdError = hWrite, hStdInput = hRead // If this is IntPtr.Zero, I get everything from stdout }; SECURITY_ATTRIBUTES pSec = new SECURITY_ATTRIBUTES(); pSec.nLength = Marshal.SizeOf(pSec); SECURITY_ATTRIBUTES tSec = new SECURITY_ATTRIBUTES(); tSec.nLength = Marshal.SizeOf(tSec); unsafe { ok = CreateProcess( null, pathToExeAndArgs, ref pSec, ref tSec, true, 0, IntPtr.Zero, null, ref startInfo, out _processInfo); } 

I have a BackgroundWorker desktop on DoWork that reads such a channel:

 success = ReadFile( _hReadStdOut, bufPtr, 1024, &read, IntPtr.Zero); 

I do not use the .Net Process class because it did not receive data from stdout until the console application sent a new line, so I also did not receive an invitation in this case.

Any help with this is much appreciated.

Greetings.

+6
source share
1 answer

I suspect the following explains what you observed:

  • If you do not define hStdInput , the child process uses a standard input device connected to the console. The child process discovers that standard input is an interactive console device and records a prompt.
  • When you define hStdInput , the child process detects that standard input is a channel and therefore neglects writing. After all, what's the point of offering a non-interactive input device?

The child process will use GetFileType(GetStdHandle(STD_INPUT_HANDLE)) to determine which type of device is connected to standard inputs. The value FILE_TYPE_CHAR points to the console. When you attach the handset to standard inputs, the standard input file type will be FILE_TYPE_PIPE .

My conclusion is that everything works as designed and designed.

+1
source

All Articles