Today we are going to cover the topic on how to send keys to another application using C#.
Full Source Code is available at:
DevInDeep/SendKeys (github.com)
This guide is a continuation on our previous post. Last week we were talking about how to get the active window using C#. This time around we are going to send commands and keystrokes to an external application.
As a result, the user will be able to connect their custom C# application to another one. Or simply put, take control over it.
If you need a refresher on the subject, please follow this tutorial first.
Or, you can continue on the next segment here.
More DevInDeep Tutorials:
- How to Scrape Web Page using C#
- Face Mask Detection using ML.NET Model Builder and C#
- How to implement Text Detection with C#
If you already know how to import the “User32.dll” and obtain the current active window, then you are all set to continue from here.
For the purposes of this demo, we are going to reuse the code from the ActiveWindowWatcher class.
In this second part, we are going to send keys to another application. Once we have the current active window, then we can send keystrokes or commands to it.
As an example, I am going to use Notepad. It’s perfect to demonstrate this demo. We can send different commands to open a file, or we can send a shortcut to close the application all together. However, Notepad also allows us to write custom text as well. So, we will connect our own text field to Notepad, and anything we write inside of it, it will be displayed there.
First things first. We are going to open Notepad. Then, we will obtain the handle of the main window. And afterwards, we are going to take control over the app from our C# code. We will send commands, for example Ctrl + O, Alt + F4 or send keyboard keystrokes. It will look just like the user is performing these operations through their physical keyboard.
Our Windows Forms C# application will control the work of Notepad. So, let’s see how we can achieve this. Remember this is all part of the Virtual Keyboard series that we are working towards.
In the first post we learned how to obtain the current active window. Now, we are going to learn how to send keys to another application (current active window). Basically, we are building a virtual keyboard. Because, that’s what a virtual keyboard does. It sends keystrokes to the currently active application/window.
But, let’s not be hasty. Let’s take each step as it comes. We are going to do one thing at a time. Let’s send keystrokes to another application first.
Send Keys Application
This is the demo application we are going to build. It is a standard Windows Forms, C# project. Once, the application is started it is running an instance of ActiveWindowWatcher.
activeWindowWatcher = new ActiveWindowWatcher(TimeSpan.FromSeconds(1));
activeWindowWatcher.ActiveWindowChanged += ActiveWindowChanged;
activeWindowWatcher.Start();
If you don’t have the code for this class, you can download it from here. Also make sure to check out the tutorial.
What this class does, is it captures the current active window every second. By clicking on the button Lock Window it will retrieve the current active windows application and save the Title and Handle of the window.
In our case, the app captured the Window Handle and Window Title of Notepad. It was able to do that via the ActiveWindowChanged event. This event is raised every time when a different window is active (comes into focus).
Here is the code for handling the event
private void ActiveWindowChanged(object sender, ActiveWindowChangedEventArgs e)
{
activeWindow = ActiveWindowModel.Create(e.WindowHandle, e.WindowTitle);
lblCurrentlyActiveWindow.Text = $"Active Window: {e.WindowTitle}";
}
activeWindow is a field inside the Form class that holds information about the current active application. So every time the focused application changes, this field will too.
By now, we have already obtained the active window. In our case, that would be the Notepad Application Window. Now it’s time to send some commands and/or keystrokes.
But, before we do that, let’s see what else do we need.
More DevInDeep Tutorials
Import and Declare Win32 functions
In order to send keys to another application we need to obtain the main window handle. This is needed because, when we click on our application form, we are the ones getting the focus. As a result, the send keys function would send keystrokes to our app. And we don’t want that. So, when we click on a button hosted by our application, we would need to activate the window we want to send the keys to.
To do that we need to use the SetForegroundWindow function. According to the MSDN documentation, this User32.dll method, brings the thread that created the specified window into the foreground and activates the window. As a result, keyboard input is directed to the window, and various visual cues are changed for the user.
This is exactly what we need. When user press a button on our application, we are going to send keys to a particular window. But then, we also need the focus back on our application, in case we want to continue on sending keystrokes. This might not be the best explanation, but bare with me. Run the demo and you will see what I am talking about.
So, let’s declare the SetForegroundWindow function in our WindowAPI.cs.
[DllImport("user32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);
public static void SetActiveWindow(IntPtr windowHandle) => SetForegroundWindow(windowHandle);
In this code block, we are importing SetForegroundWindow. You should always wrap these methods inside another one that is public, and that the client code can call. It is a good practice to wrap these methods into your own custom ones, because then you can handle any exception that comes your way. But, you can also use your own user defined types if needed. However, this is just an example, and we are not going to dig deep into best practices for this current scenario.
Send Keys Command
The SendKeys method is part of the System.Windows.Forms namespace. Please note that this can be used from Windows Forms or WPF. But, in the case of WPF applications, you do need to reference the System.Windows.Forms library. And you would also need to use the SendWait method instead of Send.
We are going to use WPF to build the Virtual Keyboard, so this change will be demonstrated in the next post.
Send Keys method is described as: Sends keystrokes to the active application. This is what we need, so let’s see how to use it. What follows is the C# implementation of the method
public static void SendKeys(IntPtr windowHandle, string key)
{
if (SetForegroundWindow(windowHandle))
System.Windows.Forms.SendKeys.Send(key);
}
In our WindowAPI.cs class we implement the SendKeys method. It takes a window handle which points to the main window of the application we want to send keys to.
Please note that in the definition of SendKeys method it says that the function sends keystrokes to the active application. This means that before we send the keys to the other application we must first activate its main window.
We do that by using the SetForegroundWindow method by providing the Window Handle of the Application we want to focus on. If the window is in focus then we simply use SendKeys.Send(key_to_send).
There is one more override of this function. Here is the C# code for it:
public static void SendKeys(IntPtr windowHandle, bool ctrlActive, bool altActive, string key)
{
if (ctrlActive)
SendKeys(windowHandle, "^{" + key.ToLower() + "}");
else if (altActive)
SendKeys(windowHandle, "%{" + key.ToLower() + "}");
else
SendKeys(windowHandle, "{" + key + "}");
}
This C# code block simply handles situations when user has pressed Ctrl or Alt.
The plus sign (+), caret (^), percent sign (%), tilde (~), and parentheses () have special meanings to SendKeys. To specify one of these characters, enclose it within braces ({})
- SHIFT +
- CTRL ^
- ALT %
We can use this function when we want to execute Ctrl + O or Alt + F4 commands on the another application.
Send Keys to Another Application C#
Let’s now look at the code behind the Send button
private void btnSend_Click(object sender, EventArgs e) =>
WindowAPI.SendKeys(activeWindow.WindowHandle,rbtCTRL.Checked,rbtALT.Checked, cboLetter.Text);
It is important to note, that the send button only sends commands to the active application. As you can see we still provide the window handle of the active application main window, but we also provide other information as well.
The second parameter, signals the method if the user has Control or Ctrl key/button active. The third parameter, signals if the Alt key is checked. Finally, we are sending the letter key code.
It may look a little bit weird how this code is wired up, but be patient. This examples leads us one step closer to building a proper virtual keyboard.
The idea behind this example is to see how we can execute shortcut commands. They should simulate the user pressing keyboard buttons such as: Ctrl + O, Ctrl + A, Alt + F4 and so on.
Key Press Event
The next C# code we are going to review is the one behind the KeyPress event handler of the text box.
private void txtText_KeyPress(object sender, KeyPressEventArgs e)
{
WindowAPI.SendKeys(activeWindow.WindowHandle, e.KeyChar.ToString());
WindowAPI.SetActiveWindow(Process.GetCurrentProcess().MainWindowHandle);
}
We want to be able to send any key stroke the user enters into our text field to Notepad. That is why we are handling KeyPress event.
This KeyPress event occurs when a character, space or backspace key is pressed while the control has the focus.
Once a Key Press event is dispatched on our main window under the text box control, we are sending that key to the active application. In our example that is Notepad. Notepad, will identify this as a user typing on the keyboard as well. Thus, it will display the characters we are inserting in our text box.
The second line of the code activates or puts focus back on our window. Because, if you remember, when sending keys to another application, the main window of that app must come into focus. So, if we focus there we will loose focus on our window, and thus we will loose focus of our text box control. As a result, right after we send the keys to Notepad, we are going to put the focus back on our main window. This will allow the user to continue typing.
The problem with this scenario is the constant window flickering. Or the constant focus transfer from one window to another. It’s distracting. This could put you off a little, but there is a solution. We will resolve this problem in our next and probably final post of these series.
How to detect File Content Change using C# – CODE-AI (devindeep.com)
Conclusion
In this article we saw How to Send Keys to Another Application in C#. Knowing how to use the Windows API and how to get the active window, combine it with the Send Keys functionality we described today, puts us very close to building a Virtual Keyboard.
There is one more thing to improve. And that is the constant flicking or focus transferring between applications. We will cover the issue and the fix in our next post.