Search code examples
c#multithreadingautomationsendkeys

How do I generate keystrokes in a non-form application


So I have a huge program and decided I should make one of the methods run in a separate thread. So I put the method in a separate class, an activated it on my form. It seemed to worked just how I wanted it to until it got to part where it gave me this error:

SendKeys cannot run inside this application because the application is not handling Windows messages. Either change the application to handle messages, or use the SendKeys.SendWait method.

I tried looking for the answer online. I think I saw something about how SendKeys only works in a Form or something.

Can anyone tell me a way to simulate a keystroke without using SendKeys, OR a way to get SendKeys to work in a different, non-form thread?


Solution

  • Your console application needs a message loop. This is done through the Application class. You will need to call Application.Run(ApplicationContext).

    class MyApplicationContext : ApplicationContext 
    {
        [STAThread]
        static void Main(string[] args) 
        {
            // Create the MyApplicationContext, that derives from ApplicationContext,
            // that manages when the application should exit.
            MyApplicationContext context = new MyApplicationContext();
    
            // Run the application with the specific context. It will exit when
            // the task completes and calls Exit().
            Application.Run(context);
        }
    
        Task backgroundTask;
    
        // This is the constructor of the ApplicationContext, we do not want to 
        // block here.
        private MyApplicationContext() 
        {
            backgroundTask = Task.Factory.StartNew(BackgroundTask);
            backgroundTask.ContinueWith(TaskComplete);
        }
    
        // This will allow the Application.Run(context) in the main function to 
        // unblock.
        private void TaskComplete(Task src)
        {
            this.ExitThread();
        }
    
        //Perform your actual work here.
        private void BackgroundTask()
        {
            //Stuff
            SendKeys.Send("{RIGHT}");
            //More stuff here
        }
    }