4

So I am attempting to run a separate program, using Process.Start().

The program will pause occasionally and wait for input. I wish to be able to send information to this process on standard input.

I am trying to make sense of the difference between creating a new process using the windows OS shell and the effects of redirecting standard input.

Exe                 UseShell    RedirectSTDIN  WINDOW Displays  OutputDisplays
cmd.exe /c program     Y               N             Y                Y
                       N               N             Y                Y
                       N               Y             Y                N

program.exe            Y               N             Y                Y
                       N               N             Y                Y
                       N               Y             Y                N

The important information is just that if I redirect standard input, then no data displays to the screen.

Why is this the case?

Normally program.exe should be writing to its stdout file descriptor.

I assume that Process.Start() creates a console process. According to MSDN:

Creating a new console results in a new console window, as well as separate I/O screen buffers.

I assume that this new window contains the console and displays the data in the console buffer. Thus, if the program outputs to stdout, we should see that data on the screen.

This is what happens normally. Why does redirecting standard input result in nothing being displayed on the screen, even though I do not touch redirect standard output?

edit:

       startInfo.WindowStyle = ProcessWindowStyle.Normal;
        //startInfo.FileName = Path.Combine(BinaryDirectory, "program.exe");
        startInfo.FileName = "cmd.exe";
        startInfo.CreateNoWindow = false;

        //startInfo.Arguments = "";
        startInfo.Arguments = "/C program.exe" + startInfo.Arguments;
        startInfo.UseShellExecute = false;
        startInfo.RedirectStandardInput = true;
        startInfo.RedirectStandardOutput = true;

According to the documentation here: https://msdn.microsoft.com/en-us/library/windows/desktop/ms681953(v=vs.85).aspx

A process can use the AttachConsole function to attach to a console. A process can be attached to one console. A console can have many processes attached to it.

I thought that my process could just hook onto the console used by the simulator and then I could write to the console. However, it returns error code 6: the console handle is invalid.

James Joshua Street
  • 3,259
  • 10
  • 42
  • 80
  • Where did you get that table from? What have you tried - where is your code? I'm asking because `Process.Start()` itself does not redirect anything. You need [Process.Start(ProcessStartInfo)](https://msdn.microsoft.com/en-us/library/0w4h05yb%28v=vs.110%29.aspx) – Thomas Weller May 27 '15 at 21:36
  • Windows doesn't provide a way of redirecting *just* standard input. You either redirect all three standard handles or none. – Harry Johnston May 27 '15 at 22:10
  • I was looking at this this morning, because of another question here. If I start cmd.exe with redirected stdin, I get "invalid file" errors, and if I send it "dir", I get "no space left on disk", so it appears that at least stderr is working. This looks like a Windows bug to me. Windows is supposed to support any combination of redirect. – glenebob May 27 '15 at 22:23
  • @HarryJohnston If I have to redirect all 3, then that means that output will no longer go to the console of the window that the process started in. Does this mean it is impossible for me to try to send the output there in my case? do I need to make a new window and display the output there? – James Joshua Street May 27 '15 at 22:49
  • Actually I've been wondering whether I was mistaken; I should perhaps reframe my earlier comment as "I don't know any way" rather than "Windows doesn't provide a way". Anyway, one workaround would be to launch the application via `cmd.exe` (or, for extra points, a command-line proxy application of your own design) rather than directly, and have it explicitly re-redirect the standard output and standard error to the console. – Harry Johnston May 27 '15 at 22:56
  • In the case of `cmd.exe`, that would be `cmd.exe /c program.exe >CON 2>&1` – Harry Johnston May 27 '15 at 22:58
  • Looks like harry's solution might work. I am still really bothered though that I can't call a process with program.exe directly and redirect its stdoutput to the window that i see on my screen. I feel like this should definitely be possible, but I just can't get it to work. i probably just don't understand something about windows. I have a window on screen. I should be able to get the console for that window and send data to it. – James Joshua Street May 27 '15 at 23:07
  • There simply are some programs that don't operate correctly when only stdin is redirected. Nothing you can do about it, it isn't your code. The most infamous example is xcopy.exe – Hans Passant May 27 '15 at 23:29
  • See the answers to [this question](http://stackoverflow.com/q/30494945/886887) for a possible solution. – Harry Johnston May 28 '15 at 00:27

1 Answers1

0

So I got it working using Harry Johnson's method:

cmd.exe /c program.exe >CON 2>&1

I also believe that I could easily create my own window, hide the window for the process and direct output to that new window.

I just wanted to be able to write to the window that the process is in. But I haven't found any way to do that. I can attach to the console of that process. But to write to that process, I require the console's screen buffer

James Joshua Street
  • 3,259
  • 10
  • 42
  • 80
  • Note that processes can only write to the console they are attached to, and can only be attached to one console at a time. – Harry Johnston May 28 '15 at 00:28
  • yes, and I read that other page linked here. http://stackoverflow.com/questions/30494945/createprocess-with-new-console-window-but-override-some-std-i-o-handles which definitely demonstrates that using C code I can easily create the window with the redirected handles. It just seems bothersome to me that I still never found a way to manually set the std out of another process after the process has already been created. to be honest it seems like a bug when i compare the inability to redirect just one handle using c# with the ease of doing it all in C. – James Joshua Street May 28 '15 at 18:54
  • I guess it's a security issue to allow one process to change another process's stdout after it has been created? but i feel like if I am in the process that started that other process that I should be able to retain some handles to do things like that – James Joshua Street May 28 '15 at 18:55