tags:

views:

559

answers:

2

I want the user to be able to have some data already in the input stream that they can change. I looked into the below function, but I'm not sure how to get the Console handle from the Console class.

    [DllImport("kernel32", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern bool WriteConsoleInput(
        IntPtr hConsoleInput,
        [Out] INPUT_RECORD[] lpBuffer,
        int nLength,
        out int lpNumberOfEventsWritten);


    public static void WriteConsoleInput()
    {
        UInt32 STD_INPUT_HANDLE = 0xfffffff6;
        IntPtr hConsoleInput = GetStdHandle(STD_INPUT_HANDLE);


        INPUT_RECORD[] lpBuffer = new INPUT_RECORD[2];

        // I tried using uChar (short) as well. 
        lpBuffer[0].Event.KeyEvent.wVirtualKeyCode = 0x41; // A
        lpBuffer[1].Event.KeyEvent.wVirtualKeyCode = 0x5A; // Z

        int nLength = lpBuffer.Length;
        int lpNumberOfEventsWritten;
        if (!WriteConsoleInput(
            hConsoleInput,
            lpBuffer,
            nLength,
            out lpNumberOfEventsWritten))
        {
            // Don't get here.
            Console.WriteLine("Error: {0}", GetLastError());
        }
    } // A breakpoint here shows that lpNumberOfEventsWritten is 2

    ...
    ...
    ...

    Console.Write("Input something: ");
    WriteConsoleInput();
    String input = Console.ReadLine();
    Console.WriteLine("input = {0}", input);

I don't see anything on the screen behind the "Input something: ". If I just hit enter, input is an empty string.

A: 

Rather than mixing managed and unmanaged (which is likely to mess up assumptions System.Console makes) I would suggest just using P/Invoke the whole way.

MSDN has an example: http://msdn.microsoft.com/library/ms685035

Richard
+1  A: 

Does this work?

public class ConsoleHandles
{
  private const uint STD_INPUT_HANDLE = 0xfffffff6;
  private const uint STD_OUTPUT_HANDLE = 0xfffffff5;
  private const uint STD_ERROR_HANDLE = 0xfffffff4;

  [DllImport("kernel32.dll")]
  private static extern int GetStdHandle(uint nStdHandle);

  public Int32 Stdin { get { return GetStdHandle(STD_INPUT_HANDLE ); } }
  //etc
}
Cheeso
Well, I don't get a 0 handle. So that's a plus. I'm still doing something else wrong.
CrashCodes