Click here to Skip to main content
Click here to Skip to main content

Sending Keystrokes to another Application in C#

By , 11 Apr 2007
 

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

  • April 11th, 2007

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Ali Zamurad
Web Developer
United States United States
Member
Ali Zamurad is a software architect and a developer. He holds Bachelor degree in Computer Science and a Bachelor of Science with honor in Physics. He has been providing software solutions, consulting services and mentoring since 1992. He has experience with a broad spectum of software development tools and languages ranges from C, C++, Visual Basic and C# to name a few.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionReading a ControlmemberRohit Ramachandaran22 Apr '13 - 21:07 
This is a great Program.
 
I need to read the list view control (SysListView32) from other exe.
 
How to do that??
QuestionSends more than 1 key sometimes :memberMD. Mohiuddin Ahmed1 Feb '13 - 20:09 
Sometimes SendKeys.Send() method sends more than one key press while it is expected to send only once ......Confused | :confused: ........
 
In one of my apps , I wrote :
SendKeys.Send("^v");
and it just pastes the clipboard text several times while it is expected to paste the text only once.
QuestionLOL UR ARABmemberKenneth Bullock14 Jan '13 - 18:25 
fun fun fun fun fun
GeneralMy vote of 5memberBlake Pritchard7 Dec '12 - 11:05 
Brilliant! Thank You!!
GeneralMy vote of 2memberMario_Arturo10 Oct '12 - 9:26 
It doesn't work if the other window is minimized
Questiongood jobmemberbalachandranM30 Aug '12 - 22:43 
Thanks man... Good job
GeneralMy vote of 1memberamabualrub28 Aug '12 - 21:45 
why did you used the user32.ddl anyway?
you can use SendKeys.Send();
to send keys to the active window... since you used the win32 you should used SendMessage() instead...
Thanks
GeneralMy vote of 5membermiguelsanc8 Aug '12 - 13:20 
A complete application!!
QuestionGreat!membermiguelsanc8 Aug '12 - 13:01 
Great Application!!!!!!!!!!! Smile | :) Smile | :) Smile | :) Smile | :) Smile | :) Smile | :) Smile | :)
Question:)membernaymyohaen2 Jul '12 - 21:54 
Smile | :) Smile | :) Thank u very much........................
QuestionWith wpf the application does not workmemberdanbenedek16 Apr '12 - 22:00 
I have a wpf application that needs to receive some keys. But using you're application I don't get them.
Anyone else has the same problem? Did you fix it? How?
AnswerRe: With wpf the application does not workmemberNic_Roche12 Jul '12 - 10:42 
Try:
 
http://wpfsendkeys.codeplex.com/[^]
QuestionCombined sends don't seem to workmemberrealcellar12 Apr '12 - 3:16 
I can only send no combinations with ctrl,alt...
When I do SendKeys.Send("{TAB}"), SendKeys.Send("{F2}") or any (just one) character, it works ok, but I can't send combinations like SendKeys.Send("^O")
This is the same for every application I try to target.
Any ideas?
(Windows 7)
AnswerRe: Combined sends don't seem to workmemberh4ckm03d30 Apr '12 - 23:19 
it's work for me. for your information SendKeys.Send("^O") with SendKeys.Send("^o") is different.
I'm trying to select all(ctrl+a) text using send command to notepad,                 
SendKeys.Send("^a"); --> worked
SendKeys.Send("^A"); --> not work
I hope it will help you.   Smile | :)
QuestionDo not lose focusmemberdemelot4 Jan '12 - 7:54 
Is it possible to send the "keystroke" to another application without losing the focus from the first application? Confused | :confused:
QuestionI really like this article.memberNitin Kumar Chaudhary21 Dec '11 - 2:21 
very help full article.
 
herman miller aeron
Questionbring second application to foreground keep failing.memberZhi Chen16 Nov '11 - 19:46 
This article is pretty good. Although I have question if anyone had tried Ali's extension
 
"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."
 
My understanding is that once the current application relinquish the focus right to another application, the "original" application cannot set the second application to foreground.
 
Essentially I want to have one application send two separate keystrokes to two separate application. One after the other. I am able to make the first application set to foreground and send keystroke; however, the attempt to bring the second application to foreground keep failing.
 
Does this make sense to anyone?
 
Zhi
GeneralMy vote of 5membersv050512 Sep '11 - 4:20 
Work good!
QuestionPGDN is missing a '{' in the sourcememberrobvon15 Aug '11 - 18:15 
lbAllKeys.Items.Add("PGDN}"); in SendKeysToApps.cs (85)
 
Great Stuff !!
GeneralMy vote of 4memberOmar Elsherif25 May '11 - 8:35 
Program worked very well, very easy, but I'd prefer using .NET rather than importing DLL functions, although i don't know whether it's possible or not.
QuestionHow to send examplememberNobody Codes That3 Jan '11 - 11:04 
Take care of the character case, example: a program supports "CTRL + S" to save a document, then use the command SendKey.Send("^s") -> (the ^ means CTRL)
GeneralWait for child window that being openedmemberqhuydtvtv25 Dec '10 - 5:26 
Hi Ali Zamurad, thank you for your amazing source code. I sucessfully sent Ctrl + O to an app to open a file, and have a problem: Could you tell me how i can wait for that child window till it is already opened? Thank you again for your code.
QuestionHelp neededmemberomairiba27 Oct '10 - 0:21 
is there way to enter password in a text box and enter the submit button. i have tried this using sendkeys but didnt work.any idea ?
 
-Omair
QuestionIt seems the demo exe not work on Windows 7. Why?memberbrant_chen16 Oct '10 - 3:53 
I disabled my antivirus program, run the SendKeys_demo as administrator role.
But nothing was poped up.
Would someone give me the reason before I try to compile the whole project?
Thank you.
GeneralTried using with Notepad and Word.memberkm774 Oct '10 - 3:16 
Sorry, but didn't work. Does gets the focus onto that application. Nothing more. Tried sending simple characters only - didn't work.
Any hints?
Generalsend keys to DirectX gamesmemberespin_andrei22 Dec '09 - 12:22 
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 thismemberminimice11 Oct '09 - 4:43 
Perform a Thread.Sleep(1000) this will bring the window into focus before sending the keystrokes. Smile | :)
 
Cheers,
Lim
GeneralRe: Doesn't work? Try thismembermasterLoki026 Oct '09 - 5:50 
Worked perfect!!! Thanks Big Grin | :-D
 
masterLoki - Trying to Understand the universe

GeneralRe: Doesn't work? Try thismemberMember 85430055 Jan '12 - 22:26 
I was having trouble sending keys to a remote app window. This worked perfectly, thanks.
GeneralSmall typomemberbloggsie25 Sep '09 - 5:05 
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 workingmemberfaltopar24 Jul '09 - 5:10 
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, IEmembersenglory16 May '09 - 19:50 
How to fix it?
Generalit doesn't workmemberselcukyazar6 May '09 - 3:24 
Hi, this program doesn't work.
Generalneed to send a "Tab" to PhotoshopmemberMember 396415919 Apr '09 - 12:39 
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 KeyboardmemberTeryaki1 Apr '09 - 14:50 
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 SendmemberKent K11 Sep '08 - 19:33 
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 controlmemberminamohebn27 Nov '07 - 1:27 
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?memberlemec10 Nov '07 - 5:32 
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...memberOleg.Kopytkov23 Sep '07 - 12:27 
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...membertoddsecond3 Nov '08 - 22:43 
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 gamesmemberraventatatatata14 May '07 - 16:18 
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 gamesmemberAli Zamurad15 May '07 - 8:38 
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 gamesmembersonaatti6 Aug '07 - 12:59 
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-combosmemberDrexur20 Apr '07 - 11:57 
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
 

 
Confused | :confused: Confused | :confused:
 


 
/Anders
GeneralRe: Sending special key-combosmemberAli Zamurad20 Apr '07 - 12:12 
Hmmm. Interesting problem. I will see if I could do that.Sniff | :^)
GeneralRe: Sending special key-combosmemberDrexur21 Apr '07 - 5:55 
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-combosmemberDrexur22 Apr '07 - 5:32 
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...memberXChronos17 Apr '07 - 6:33 
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...memberAli Zamurad20 Apr '07 - 10:37 
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...memberXChronos20 Apr '07 - 10:52 
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.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130516.1 | Last Updated 11 Apr 2007
Article Copyright 2007 by Ali Zamurad
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid