Click here to Skip to main content
Email Password   helpLost your password?

Screenshot - SendKeys.jpg

Introduction

Sometimes in the life of a developer, a need arises to control another application from his/her application. It may be to provide automation services, to give control or for the ease of use of customers who are not very computer savvy.

There are many different tools and technologies available these days to accomplish that kind of automation. Integration between applications depends on the services that applications can expose or provide. For example, in the good days on Windows 3.1, Data Dynamic Exchange (DDE) or some screen scrapping techniques were used to accomplish that. DDE utilized the basic Windows Messaging Layer functionality. Since the DDE was limited to transferring data between two running applications, with the emergence of Object Linking and Embedding (OLE) automation became more prominent to these integration tasks with much confidence. OLE became the backbone for technologies such as Component Object Model (COM). Now-a-days different applications provide their object models to achieve the same kind of integration services. A good example of it would be the Microsoft Office line of products. Microsoft Office such as Excel or Word provide their object models to integrate with them.

But still from time to time there are applications which do not provide or expose any of the above mentioned techniques that can be utilized to do the integration with them. The only way to control these kinds of applications is emulating keystrokes to them to make them act as they would if they were in focus and taking keyboard input.

This small sample application shows how to accomplish this emulation of sending keystrokes to applications using Microsoft .NET Framework using C#.

SendKeys Application

This is very simple WinForm application, which basically utilizes .NET 2.0 SendKeys class to do most of its work. SendKeys class is defined in System.Windows.Forms namespace. One issue with the SendKeys class is it can only send keystrokes to the active application. Active application is the one which is in focus to accept keyboard input. To make any Windows active from another application we have to take help from the Windows native API SetForegroundWindow. SetForegroundWindow requires the Windows handle to bring it to the front. To get the Window handle I use yet another native API FindWindow. FindWindow takes two arguments, the first is the pointer to a null-terminated string that specifies the class name used to register the Window class and if this is null then the second argument is a Pointer to a null-terminated string that specifies the Window name (the Window's title).

int iHandle = NativeWin32.FindWindow(null, txtTitle.Text);
            
NativeWin32.SetForegroundWindow(iHandle);  

Windows native APIs can be incorporated into a .NET application via PInvoke. PInvoke functionality is by inclusion of System.Runtime.InteropServices namespace. Adding the Windows native APIs signature could be a daunting task specially if you do not have background and/or experience in C++ development. To facilitate this task some good guys brought up a very good site that can get you a jump start. In this project NativeWin32 class provides encapsulation for the Windows native API and also exposes their functionality.

As you have some idea about the driving force for this application creation, I will now explain the usability of the application for your reference.

When you launch this application it will display a single Winform as shown with an Auto radio button selected. This 'Auto' selection shows a combobox under 'Windows Title' filling up with all the top level Windows applications running on the machine. This service is only provided for ease of use. You can select 'Manual' which would display a text box to type the Windows title of the application you want to send keys to.

The 'Refresh' link would help to update the combobox entries to the currently running Windows. To update the combobox with the currently running applications, we again take a simple approach and call the native Windows API as shown below:

/// <summary>

/// Get all the top level visible Windows

/// </summary>

private void GetTaskWindows()
{
    // Get the desktopwindow handle

    int nDeshWndHandle = NativeWin32.GetDesktopWindow();
    // Get the first child window

    int nChildHandle = NativeWin32.GetWindow(nDeshWndHandle, 
                        NativeWin32.GW_CHILD);
                        
    while (nChildHandle != 0)
    {
        //If the child window is this (SendKeys) application then ignore it.

        if (nChildHandle == this.Handle.ToInt32())
        {
            nChildHandle = NativeWin32.GetWindow
                (nChildHandle, NativeWin32.GW_HWNDNEXT);
        }

        // Get only visible windows

        if (NativeWin32.IsWindowVisible(nChildHandle) != 0)
        {
            StringBuilder sbTitle = new StringBuilder(1024);
            // Read the Title bar text on the windows to put in combobox

            NativeWin32.GetWindowText(nChildHandle, sbTitle, sbTitle.Capacity);
            String sWinTitle = sbTitle.ToString();
            {
                if (sWinTitle.Length > 0)
                {
                    cboWindows.Items.Add(sWinTitle);
                }
            }
        }
        // Look for the next child.

         nChildHandle = NativeWin32.GetWindow(nChildHandle, 
                        NativeWin32.GW_HWNDNEXT);
    }
} 

Once the Window is decided with either of above defined way, you can select keys you want to send from the 'All Keys' listbox and press the 'Add' link to add them into the 'Keys to Send' listbox. 'All Keys' listbox displays all the possible keys that are supported and can be sent out to other applications. You can select multiple keys at the same time with the normal selection behavior provided by the listbox. One caveat to be aware of though, the selection with the added sequence from the 'All Keys' as they appear in the listbox and not as the order of your selection. Order of selection functionality can be added with ease but I leave it as an exercise to the readers.

'LoadKeys' and 'SaveKeys' give the serialization and deserialization abilities for the keys displayed in 'Keys to Send' listbox. 'Delete' link helps in removing selected keys from the 'Keys to Send' listbox.

'Replicate' link provides the functionality to multiple the keystroke 'n' times of the selected keys from the 'Keys to Send' listbox. Again the selection will multiply in sequential order.

After setting all these, pressing the 'Send Keys' button would activate the application matching with the Windows title and start sending keystrokes as someone is using a keyboard to that application.

Application Extension Possibilities

This application gives you a general idea on how to use sending keystrokes mechanism to another application. One possible extension to this approach could be sending keystrokes to multiple applications at the same time by extending the selection of multiple applications by using listbox rather then combobox.

History

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
Generalsend keys to DirectX games
espin_andrei
13:22 22 Dec '09  
tried your program to send simple ESC command (to close menu in the game) to FIFA 09 game - no result at all. Does it need some API hooks or the only way to do it is low level interrupts etc?
GeneralDoesn't work? Try this
minimice
5:43 11 Oct '09  
Perform a Thread.Sleep(1000) this will bring the window into focus before sending the keystrokes. Smile

Cheers,
Lim
GeneralRe: Doesn't work? Try this
masterLoki0
6:50 26 Oct '09  
Worked perfect!!! Thanks Big Grin

masterLoki - Trying to Understand the universe

GeneralSmall typo
bloggsie
6:05 25 Sep '09  
Hi,
Nice work.
I noticed a small type with the definition for page down - missing opening '{'
lbAllKeys.Items.Add("PGDN}");

Thanks,

Joe
Generalextract of SendKeysToApps not working
faltopar
6:10 24 Jul '09  
I extracted and modified the pertinent code to do a sendkeys:

int iHandle = NativeWin32.FindWindow(null, "My Chat");

NativeWin32.SetForegroundWindow(iHandle);

string keys = "{BS}";
System.Windows.Forms.SendKeys.Send(keys);

The only basic difference being I hard coded the application (which is the one I am executing).
When I do the same task ({BS} to program "My Chat") from your sendkeys program it works fine,
however my code executed from within "My Chat" does not.
Any Ideas?
Thanks,
David Parker (pongfar@comcast.net)
GeneralDoesn't work at all with MS Word, Excel, IE
senglory
20:50 16 May '09  
How to fix it?
Generalit doesn't work
selcukyazar
4:24 6 May '09  
Hi, this program doesn't work.
Generalneed to send a "Tab" to Photoshop
Member 3964159
13:39 19 Apr '09  
I have application for image editing and I am trying to send "Tab" key to photoshop
I am using vb.net 2008. I try to convert the code to vb but I don't all you code does work
to send the tab to photoshop . but I need it for Vb and also automatically

Sam
www.thegreengenie.com
GeneralArabic Keyboard
Teryaki
15:50 1 Apr '09  
Thank you very much

it helped a lot to develope my tool "ArabicKeyboard".
I had to change the NativeWin32 Class to allow universal code: [DllImport("user32.dll", CharSet = CharSet.Unicode)]

The tool is free and can be downloaded from my site http://teryaki.eu/?p=331
It also support Farsi, Urdo and Hebrew laanguages

Thanx again
GeneralSendWait may work better than Send
Kent K
20:33 11 Sep '08  
This waits for the application being sent commands to process them, ensuring that it's ready to receive more and work probably more as you wish/had planned.
GeneralSendKeys and webborwser control
minamohebn
2:27 27 Nov '07  
I am using Sendkeys to press tab and enter on the webbrowser.
I created two buttons, one for the tab and the other for enter.
In the event handler for both buttons, I first setfocus on the webbrowser and then use SendKeys.Send("{enter}") or tab. Actually, they sometimes work and sometimes not. However, when I call a function that does the previous work from the event handler , it does not work at all. Could anybody help me??
QuestionSend key-press to remote computer on network?
lemec
6:32 10 Nov '07  
First off; nice work Smile

Is there a way to send a key-press to a remote computer on a local network? Fx send a key-press from a laptop to a desktop computer? Perhaps some new features in .NET 3.5?

Regards - LeMec
Generalis there a way to...
Oleg.Kopytkov
13:27 23 Sep '07  
send keys without selecting the window first? I would like to be able to send keys without having to make the window to an active window first.
GeneralRe: is there a way to...
toddsecond
23:43 3 Nov '08  
Oleg.Kopytkov wrote:
send keys without selecting the window first?


Use SendMessage, one call per character

...

using System.Runtime.InteropServices;


[DllImport("user32.dll")]
public static extern int SendMessage(
uint hWnd, // handle to destination window
uint Msg, // message
uint wParam, // first message parameter
uint lParam // second message parameter
);

public const int WM_CHAR = 0x0102;


// feeble version of SendKeys, but able to send to non-front window
public static void SendKeysAV(uint hwnd, string keys) {

if (keys.Length == 0) return;
uint k;
string rest = "";
switch (keys) {
case "{ESC}": k = (uint)Keys.Escape; break;
case "{ENTER}": k = (uint)Keys.Return; break;
case "{TAB}": k = (uint)Keys.Tab; break;
case "{DELETE}": k = (uint)Keys.Delete; break;
case "{HOME}": k = (uint)Keys.Home; break;
default:
k = keys[0];
rest = keys.Substring(1);
break;
}
int rc = SendMessage(hwnd, WM_CHAR, k, 0);
SendKeysAV(hwnd, rest);
}
Generalsend keys to games
raventatatatata
17:18 14 May '07  
I have been using this method to send keystrokes to whatever the foreground window is. When I do so, there is significant lag between when it sends and when it's recieved, and in the case of a game, the keystroke does not appear unless it's a menu. I was hoping to use this method for some custom input devices but it appears to be unreliable. Do I need to write some kind of custom driver to accomplish this, or is there some way of accessing direct input API's to do so?

Cheers
GeneralRe: send keys to games
Ali Zamurad
9:38 15 May '07  
The lag is because of your CPU slowness. Please look below as XChronos tried some options. Moreover you could write direct calls from a C++ program SendMessage API. Basically in .Net some of the API under the hood call some native API and because of that some latency occurs. Of course if you want to go to the low level drivers using interrupt then things will be much faster, but the trade off is you have to work with low level just a one level above the machine code which could be daunting task all in itself.;)
GeneralRe: send keys to games
sonaatti
13:59 6 Aug '07  
I have no lag at all but I'm also wondering if why it's not possible to send keystrokes to a game, again if have an acive menu, console or whatever it's possbile but what about for instance pressing F5 which would take a screenshot in many games, any ideas ?
GeneralSending special key-combos
Drexur
12:57 20 Apr '07  
Hello!

I have experimented with this very nice code, and would like to use it for the following

purpose:

Create an application that has a button, and then clicked sends the emulation of the "CTRL

+ §-key".

I have been able to to send stuff like "CTRL-C" and "CTRL-V"
//sendkeys.send("^c") equals to "CTRL-C"
//sendkeys.send("^v") equals to "CTRL-V"

The problem seems to be that I do not know how to send the §-key...

Anyone who has a sugestion to my problem?
I was think of something like sending CTRL+ALT and ASCII-code for the §-key:
//sendkeys.send("^%0x167")
Does not work though...Probably something wrong



ConfusedConfused




/Anders
GeneralRe: Sending special key-combos
Ali Zamurad
13:12 20 Apr '07  
Hmmm. Interesting problem. I will see if I could do that.Sniff
GeneralRe: Sending special key-combos
Drexur
6:55 21 Apr '07  
Oki, Cool let me know if you are having any success...
And if i should help you with some testing
Found this site today, could perhaps help me but, using VS and C# would be a better solution.
http://www.autohotkey.com/[^]
/
Anders
GeneralRe: Sending special key-combos
Drexur
6:32 22 Apr '07  
Does anyone know if it is possible to sendkeys with C# to a specific "contol" on another Form/application.

Just like in authotkey, described here:
http://www.autohotkey.com/docs/commands/ControlSend.htm[^]

If it is possible, how do I do it?





GeneralGreat wotk but...
XChronos
7:33 17 Apr '07  
Sometimes didn`t work, I try sending keys with the demo to the notepad and sometimes they appear and sometimes not. Maybe if you wait a little more before sending??? Please verify, because I want to use it, it's just a great work, and tell me. Thanks in advance.
GeneralRe: Great wotk but...
Ali Zamurad
11:37 20 Apr '07  
Just make sure that the window you are trying to send key stroke is getting in focus. If forever reason if the window is not getting focus then it will not work.Cry
GeneralRe: Great wotk but...
XChronos
11:52 20 Apr '07  
The windows i'm sending the key stroke always get focus, but sometimes the key stroke appear and sometimes not. I'm using the demo, i'm too lazy to analize your code and check it out, but I will do it soon. Please verify it with both the demo and the debbuger.
GeneralRe: Great wotk but...
Ali Zamurad
12:59 20 Apr '07  
Do not use the debugger. Since when you are in debugging mode then you focused window is your debugging session and of course SendKeys class will send the keystrokes to debug windows which you do not want. I wish that dotNet folks should have made sendkeys class extendable so you could specify which window you desire to send keys to.Mad


Last Updated 11 Apr 2007 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010