简体   繁体   中英

How to capture standard input in a Winforms application

I have a form in C# where I need to capture standard input.

I have this code so far (taken from https://daveaglick.com/posts/capturing-standard-input-in-csharp ):

        string stdin = null;
        if (Console.IsInputRedirected)
        {
            using (Stream stream = Console.OpenStandardInput())
            {
                byte[] buffer = new byte[1000];  // Use whatever size you want
                StringBuilder builder = new StringBuilder();
                int read = -1;
                while (true)
                {
                    AutoResetEvent gotInput = new AutoResetEvent(false);
                    Thread inputThread = new Thread(() =>
                    {
                        try
                        {
                            read = stream.Read(buffer, 0, buffer.Length);
                            Console.WriteLine("LEIDO " + read.ToString());
                            Console.WriteLine("CON CONSOLE.IN ->" + Console.In.ReadLine() + "<-");
                            gotInput.Set();
                        }
                        catch (ThreadAbortException)
                        {
                            Thread.ResetAbort();
                        }
                    })
                    {
                        IsBackground = true
                    };

                    inputThread.Start();

                    // Timeout expired?
                    if (!gotInput.WaitOne(100))
                    {
                        inputThread.Abort();
                        Console.WriteLine("ABORTADO!!!");
                        break;
                    }

                    // End of stream?
                    if (read == 0)
                    {
                        stdin = builder.ToString();
                        ProcessInput(stdin);
                        Console.WriteLine("LEYÓ ->" + stdin + "<-");
                        break;
                    }

                    // Got data
                    builder.Append(Console.InputEncoding.GetString(buffer, 0, read));
                }
            }
        }

The problem is that even if I press any key, no data is read by the call to "stream.Read()" method.

I have tried with Console.In.ReadLine() and Console.ReadLine() but nothing works.

However, if I place a TextBox control in the form, and move the focus to it, any pressed key is written in the TextBox.

I need to capture keyboard keys before it is sent to TextBox.

By the way, Form.KeyPress property is not an option in my situation, but just in case, I have set it to true, but it did not work either.

Form key events are not options either because all this call should be made by an external DLL that I am loading dynamically.

Any help, please?

Thanks Jaime

Use Control.KeyDown event.

Key events occur in the following order:

  • KeyDown
  • KeyPress
  • KeyUp

According to documentation KeyDown occurs when a key is pressed while the control has focus.

So if you are not inside TextBox it will not catch anything BUT you can fix that too.

If you want to catch ANY key pressed inside FOCUSED form simply set yourForm.KeyPreview = true and it will catch any key pressed as long as form is in focus (not particular control inside form)

Be careful, if you want to listen to key only inside Text Box, attach event to Text Box, if you want to listen to keys anywhere in form enable KeyPreview and attach KeyDown event to Form

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM