-1

This seems trivial, but google only gives me powershell-related stuff and how to implement pipelines within programs.

I'm trying to consume input arguments from the (standard command processor cmd.exe for Windows 7, not powershell) command line pipeline on windows like 'more' does.

I'm trying to get this to work with two self-created .exe files:

  1. randgen (creates a random number and writes it to the console)
  2. wordwrite (the c# program that I want to consume this random number from the pipeline)

And using two common windows executables to test and model the behaviour:

  1. echo (writes input to console)
  2. more (displays output one screen at a time, can consume input from the pipeline)

Here's the current content of my Main function in wordwrite:

    static void Main(string[] args)
    {
        string ouname = args[0];
        DocWrite(ouname);
    }

and the behaviour trying to naively pipe output from randgen into wordwrite:

D:\code>randgen | wordwrite

Unhandled Exception: System.IndexOutOfRangeException: Index was outside the bounds of the array.
   at ADDoc.ADOUDoc.Main(String[] args)

(plus a popup telling me wordwrite.exe has stopped working)

Which is the behaviour of trying to consume a null array of arguments as input:

D:\code>wordwrite

Unhandled Exception: System.IndexOutOfRangeException: Index was outside the bounds of the array.
   at ADDoc.ADOUDoc.Main(String[] args)

So the output of randgen isn't being read from the pipeline correctly as an argument to the wordwrite executable's args array (thanks @Peter Duniho for explaining the difference between stdin and how argument assignation works). Contrast that with the behaviour of the 'more' executable:

D:\code>randgen | more
56929227

That said, this 'pipeline-awareness' seems to be inherent to the 'more' executable itself, as another common windows executable, echo.exe, is just as pipeline-blind as wordwrite.exe:

D:\code>randgen | echo
ECHO is on.

D:\code>echo blah
blah

D:\code>echo
ECHO is on.

Here we can see that the attempt to use the pipeline is effectively the same as providing no arguments for echo.exe (contrasted in the middle with behaviour when an argument is provided).

Which suggests there is something I can add the the body of my Main function in wordwrite.exe to enable pipeline-consuming behaviour like the 'more' executable does. Does anyone know how this is done?

Bruno
  • 111
  • 6
  • Just an observation here. I don't think "pipe more" or "pipe echo" are commands that get passed to the exe you're trying to run. I think it's something used internally by cmd.exe. And since there's no such thing as "pipe wordwrite" cmd.exe throws an exception. In other words I don't think you can pass pipe commands to a program, therefore you can't create a program that handles them. I think pipe commands are reserved for the shell. – Sean O'Neil Nov 27 '17 at 04:08
  • _"So the output of randgen isn't being read from the pipeline correctly"_ -- that's not the correct conclusion. The reason you get the exception is that arguments to a console program have _zero_ to do with the stdin stream. You'll never get anything from stdin put into the `args` array, because that's not what that array is for. – Peter Duniho Nov 27 '17 at 04:09
  • @Peter Duniho: So is there a better way to phrase that? I gather you're saying that the 'args' array is for space-separated arguments provided after the program name like so: "program.exe arg1 arg2". Fair enough. Though that doesn't tell me what is 'for' program.exe to consume data from the pipeline to use in execution, as in: " | program.exe". Still, your reference to stdin allowed me to refine my query enough to find this: https://stackoverflow.com/questions/199528/c-sharp-console-receive-input-with-pipe, which appears to do the trick, so thank you. – Bruno Nov 27 '17 at 04:25
  • It's not entirely clear to me what you need help with. `more.exe` has a specific behavior, which is that it can both consume redirected stdin (i.e. from `|` or `<`) _and_ it can receive user input as well. The link you reference simply discusses consuming redirected input, which IMHO is not even all that interesting (since it "just works", if you are using the `TextReader`-based methods in the `Console` class). Is that all you needed, or do you also want to know how to handle user input while consuming the redirected stdin? – Peter Duniho Nov 27 '17 at 04:30
  • That really is all I needed, my confusion stems from the triviality of this kind of interaction in powershell, in linux shells etc. vs the less intuitive behaviour here. When I say I want to consume input 'like more', a simplified way of saying that is to say I want the program to be able to assign data from stdin to a variable. I'm used to being able to take arguments and just say 'accept this from the pipeline' in Powershell, and with the 'just works' pipeline behaviour of linux. Having built-in executables that don't take data from stdin was already confusing me. – Bruno Nov 27 '17 at 04:44
  • You seem to be conflating a command-line interface like PowerShell, *nix shells (bash, bourne, etc.), or the Windows CLI (i.e. cmd.exe) with a _program_ that operates within the context of a shell. E.g. PowerShell is just a way to run programs and cmdlets, and inside those tools there is still code that looks very much like what's needed in C# to consume a redirected stdin. In any case, given your statements here, it does seem to me your question is a duplicate of the one you found. It just wasn't clear what you were asking in the first place. – Peter Duniho Nov 27 '17 at 05:14
  • Possible duplicate of https://stackoverflow.com/questions/199528/c-sharp-console-receive-input-with-pipe – Peter Duniho Nov 27 '17 at 05:14

1 Answers1

0

You can read data 'from the pipeline' (effectively, the stdin stream*) by using the Console.ReadLine() method, like so:

    static void Main()
    {
        string ouname = Console.ReadLine();
        DocWrite(ouname);
    }

*The pipeline is a tool to direct the output of one process (stdout) to the input (stdin) of another one. So when you think of 'consuming input from the pipeline', think 'assign stdin to a variable that you then do stuff with'.

Reference: C# Console receive input with pipe

Bruno
  • 111
  • 6
  • And how does this let you implement something that works like `more.exe`? Where in the above is the code to handle pausing output and waiting for user input? – Peter Duniho Nov 27 '17 at 04:36
  • I'm not sure this question and answer provide sufficient novel value not to be closed as a duplicate of the referenced question and answer, which is unfortunate as the wording is sufficiently different that it could draw in those searching for the same answer with different terms. – Bruno Nov 27 '17 at 04:37
  • @Peter Duniho, it doesn't and nowhere, my reference to 'more.exe' is simply that it's the only built-in exectuable I'm aware of that takes data from stdin. – Bruno Nov 27 '17 at 04:52