Question

I'm trying to figure out how to read from the standard input stream of my own WPF application but I can't find a way to get the stream. The standard way to do it,

Console.ReadLine()

returns Null(Nothing) immediately. I'm assuming because it's not a console application and no console window is open. How can I read from standard input in a WPF application?

Some backgroud: I'm trying to read text being sent in by an external device (magnetic card reader) which sends its data to stdin of the currently focused application. I can set focus on a TextBox and then read the data from there if I have to but I would much rather read the data directly if possible to avoid a host of possible issues.

Edit: Even though Daniel Pratt solved my original problem it would still be nice to figure out how to read from stdin. If you can answer it I'll change the accepted answer.

Was it helpful?

Solution

I was under the impression that devices of this sort usually function as a keyboard (this would make the part about the TextBox from the original question make sense). I think you just need to hook some keyboard events.

OTHER TIPS

Console.ReadLine() works in WPF apps, at least when I try by piping via command line. Maybe null was explicitly being sent by the card reader's driver (could signify something).

For folks like me who came looking for a general how-to, here's a demo of what I did (assumes null means end of input):

  1. Create a fresh, new "WPF Application" project.
  2. Add this to MainWindow's constructor in MainWindow.xaml.cs:

    if (Console.In.Peek() != -1) // If there's input on the standard input stream.
    {
        var fullInput = new StringBuilder();
        var currentLine = string.Empty;
        while ((currentLine = Console.ReadLine()) != null)
            fullInput.AppendLine(currentLine);
    
        MessageBox.Show($"Input: {fullInput}");
    }
    else
        MessageBox.Show("No input detected on stdin");
    
  3. Build, and run with and without piping a string in from the command line.

    • Without input:

      c:\> WpfApplication1.exe
      

      enter image description here

    • With input:

      c:\> echo "testing 1, 2, 3" | WpfApplication1.exe
      

      enter image description here

Looking at the .NET framework code for reading/writing from the stdin/stdout streams, it appears as if there is nothing reliant on the console window in fact. The code appears to simply make use of various native Win32 calls, firstly to GetStdHandle to get the handle of the standard in/out stream, and the creates a __ConsoleStream class which is a managedd wrapper over the Win32 ReadFileNative and WriteFileNative functions. So really, I don't see any reason why Console.ReadLine shouldn't work... It's worth checking whether calls to read from stdin using Console succeed when you put the code directly in the Main function. I suppose the issue here could be something to do with the application type as recognised by Windows, but I don't see why non-console apps should be restricted from reading from stdin/writing to stdout. The other possible cause could be the thread from which you are making the calls. Anyway, have a go testing this and let me know the results. If you still don't have any success, I'll try to do some of my own testing as I'm curious as to the solution.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top