MS.COM Operations Tools Team WebLog

Hey - What does this button do?

Shell in .NET!

Maybe many of you out there in Developer Land are already aware of this, but I need to point out that you can indeed shell, sleep, and SendKeys using the new fancy C# and .NET Framework. You see, a few months ago, I needed to come up with a quick and dirty demo of a Windows application. Then I came up with the brilliant notion of shelling to it, then sending keystrokes to it to demo the app. I wondered, can you still peform this most crude form of application interoperability with the most elegant C# and .NET?

The answer is a big YES! Check this C# code out:

using System;
using System.Collections.Generic;
using System.Text;

using System.Diagnostics;
using System.Threading;
using System.Windows.Forms;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            //"shell" to open WordPad
            Process myProcess = new Process();
            myProcess.StartInfo.FileName = @"wordpad.exe";
            myProcess.StartInfo.Verb = "Open";
            myProcess.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
            myProcess.Start();
            //pause for 1/2 second
            Thread.Sleep(500);
            //open the Format dialog
            SendKeys.SendWait("%OF");
            //set the font size, then ENTER
            SendKeys.SendWait("{TAB}{TAB}48~");
            //type some text
            SendKeys.SendWait("Hello world");
        }
    }
}

The above code is a console EXE program that brings up WordPad, then types a big "Hello World", with a 0.5 second sleep in between to give WordPad time to open. I love this code -- it is SO old school. It warms my heart that you can still stoop to this level. I hope you enjoy it as much as I.

For a list of all of the SendKeys codes, see the following page in MSDN online:

http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemWindowsFormsSendKeysClassTopic.asp

Happy coding!

- Eric

Published Friday, February 04, 2005 3:30 PM by mscomts

Comments

 

irrationalRobot said:

Hey yoda- I've only done my programming in .net land (I'm a rookie), so how does this bad boy work?

<i>SendKeys.SendWait("%OF");</i>

Is SendKeys a static method for one of those classes you are <i>USE</i>ing?
February 5, 2005 9:50 AM
 

Eric said:

Howdy there, robot
Let me it down for you.

SendWait is a public method of the SendKeys class, in the System.Windows.Forms namespace, of the mighty .NET Framework. And in order to use this magic, you need to add a reference to your project, pointed to the DLL for System.Windows.Forms -- mine was located at <file\\C:\WINDOWS\Microsoft.NET\Framework\v2.0.40607\System.Windows.Forms.dll>.

You might notice the "v2" in there, which is a sign that I am running the Visual Studio 2005 Beta. Have no fear, all of this code shoudl work in VS 2003, .NET FX v1.1, as well.

Returning to my code, the line:


SendKeys.SendWait("%OF");


sends keystrokes to the active application, which would be WordPad in the case. With WordPad open and active, the "%" character is the code for the ALT key, which puts the focus up at the application menu. Next, the "O" is the shortcut key to drop down the Format menu. Finally, the "F" keystroke opens the Font dialog.

Putting these keystroke sequences together usually requires some progressive experimentation. You manually walk through the keystrokes, while coding your steps into the characters you pass to the SendWait method. I broke up my steps into three runs,
but this is not required, and has the same effect as putting all of the keystrokes in a single run. Coding all of the SendKeys as:


SendKeys.SendWait("%OF{TAB}{TAB}48~Hello world");


works just as well, but is a little harder to read. Considering that the SendKeys codes are pretty cryptic, it is wise to break the runs into related chunks, inserting comments for each. But, then again, we are talking style points here for a kind of programming that is on about the lowest rung of the coding style ladder! :)

To cover the bigger picture, let's talk about the "shell" and sleep parts of the code now.

The shell part really has no "shell" involved. It is actually working the Process class in the System.Diagnostics namespace:


http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemDiagnosticsProcessClassTopic.asp


That MSDN page describing the Process class has a good and meaty code samples to learn from. I call it shelling because that is what it was called back in good ol' Visual Basic, where I honed these tricks. Visual Basic v6, before the advent of .NET, still supports a Shell function:


http://msdn.microsoft.com/library/en-us/vbenlr98/html/vafctShell.asp


The task accomplished by Shell and Process.Start is much the same. Essentially, you are mimicking using the Windows file Explorer to either Open, Edit, Print, or do some other action with a file. It does not have to be Opening an executable. For example, you might Delete a file or Copy it to the clipboard. I have not tried all of these things to verify they work, but that is the general idea.

Finally, the sleep part is a clean and tidy one-line affair, running the Sleep method of the Thread class in the System.Threading namespace:


http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemThreadingThreadClassSleepTopic.asp


It takes either an integer for milliseconds, or you can also pass it a more-elegant TimeSpan structure. However, this use of sleeping the thread exposes some ugliness of this style of application interoperability. My use of 0.5 seconds is a guess for a safe time span to wait while WordPad loads. Some computers will open WordPad slower, others faster. So 0.5 seconds might not work on all computers. If WordPad is not open after 0.5 seconds, the SendKeys will be sent to whatever the last active application was. Yikes!

More problems with this code:

1. The host computer might not have WordPad, or your target application, installed. I chose WordPad because most Windows computers have it.
2. Some other process might activate some window other than WordPad during the SendKeys, which might cause the keystrokes to be sent the new window. Yikes again!
3. This kind of interop. is very slow and inefficient. There are much faster routes in many cases, such as how Microsoft Office applications can be automated via their core object models in C#.


More joys with this code:

1. No dependencies required for object models exposed as API's. If you can keyboard it, you can automate it.
2. You get to see the screen "dance"! So much of the programming we do is executed so quickly, and the execution is completely hidden from view. Therefore, it is gratifying to see your computer display flash and change before your very eyes. It is a joy to witness your computer do things much faster than you can, making you appreciate the work being done.


Boy, has this been a long winded response. Thanks for asking, Robot, I guess I need to speak my mind! After reviewing all of this, it comes to mind that shelling and SendKeying would be a useful way to teach programming. Instead of ending up with some wimpy little Console.Write output, why not have your first programs write BIG OUTPUT in WordPad? Or your first program could send email for you while you watch the show!

And for Test Professionals, SendKeys is a valid method for simulating user input. How about them apples!

Q.E.D.
- Eric



February 5, 2005 1:06 PM
 

Sean Gephardt said:

Nothing like going back to the basics...
February 10, 2005 4:21 PM
New Comments to this post are disabled

This Blog

Syndication

Tags

No tags have been created or used yet.

News

All opinions posted here are those of the author(s) and are in no way intended to represent the opinions of our employer. This is provided "AS IS" with no warranties, and confers no rights. Use of included code samples are subject to the terms specified in the Terms of Use.

© 2009 Microsoft Corporation. All rights reserved. Terms of Use  |  Trademarks  |  Privacy Statement
Microsoft
Page view tracker