30

I need to control other application by simulating mouse movement and keyboard input. How do I accomplish this in C#? Is it even possible?

3

6 Answers 6

47

Have you looked at White TestStack?

Sample code:

Application application = Application.Launch("foo.exe");
Window window = application.GetWindow("bar", InitializeOption.NoCache);

Button button = window.Get<Button>("save");
button.Click();

I don't think it can get better than that. The library is created by ThoughtWorks.

Sign up to request clarification or add additional context in comments.

4 Comments

I was trying to browse White project's documentation and it started giving errors! BTW, 'White' will give you OO approach to control Windows based applications.
I'm trying to access Spotify (A music program) and click the play button, but it seems to be completely graphical because I can't find any handles or anything with spy++. How would I do this?
@PontusMagnusson did you managed it somehow? I am having the same issue as you.
@Twenty I did, but unfortunately I dont have the code anymore. I believe I queued windows events to control the different elements of the application. Today I think I'd use the Spotify API tho.
4

See "To send a keystroke to a different application" on this page:

http://msdn.microsoft.com/en-us/library/ms171548.aspx

Comments

3

You can use p/invoke, I stole the following code for mouse clicks in random spots on a button with a known handle:

    [Flags]
    public enum MouseEventFlags
    {
        LEFTDOWN = 0x00000002,
        LEFTUP = 0x00000004,
        MIDDLEDOWN = 0x00000020,
        MIDDLEUP = 0x00000040,
        MOVE = 0x00000001,
        ABSOLUTE = 0x00008000,
        RIGHTDOWN = 0x00000008,
        RIGHTUP = 0x00000010
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct Rectangle
    {
        public int X;
        public int Y;
        public int Width;
        public int Height;
    }

    private static void Click(IntPtr Handle)
    {
        lock (typeof(MouseAction))
        {
            Rectangle buttonDesign;

            GetWindowRect(Handle, out buttonDesign);
            Random r = new Random();

            int curX = 10 + buttonDesign.X + r.Next(100 - 20);
            int curY = 10 + buttonDesign.Y + r.Next(60 - 20);

            SetCursorPos(curX, curY);
            //Mouse Right Down and Mouse Right Up
            mouse_event((uint)MouseEventFlags.LEFTDOWN, curX, curY, 0, 0);
            mouse_event((uint)MouseEventFlags.LEFTUP, curX, curY, 0, 0);  
        }
    }

    [DllImport("user32.dll")]
    static extern bool SetCursorPos(int X, int Y);

    [DllImport("user32.dll")]
    private static extern void mouse_event(
        long dwFlags, long dx, long dy, long cButtons, long dwExtraInfo);

    [DllImport("user32.dll")]
    static extern bool GetWindowRect(IntPtr hWnd, out Rectangle rect); 

Comments

2

you can use AutoIT, it's freeware, and it has a dll version that you can import into C# (DllImport). It allows you to click on controls, write strings to edit boxes, make combobox selections etc on another application from C#.

Comments

1

Use the SendMessage Native Win32 API. DllImport this method from the User32.dll. You can use this API to send both keyboard & mouse messages

Comments

1

I tried to do the same: to use the mouse i used this class

(you need to add using System.Runtime.InteropServices;)

public class MouseClick1    //public is important here**
    {
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint cButtons, uint dwExtraInfo);


        private const int MOUSEEVENTF_LEFTDOWN = 0x02;
        private const int MOUSEEVENTF_LEFTUP = 0x04;
        private const int MOUSEEVENTF_RIGHTDOWN = 0x08;
        private const int MOUSEEVENTF_RIGHTUP = 0x10;


        public int CoordX { get; set; }    
        public int CoordY { get; set; }

                public void Click1()
        {

            Cursor.Position = new Point(CoordX, CoordY);

            mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
            mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);

        }

    }

and after on your form1 (presuming the name is form1) you can

 public partial class form1 : Form
    {

 MouseClick1 button1 = new MouseClick1();
 MouseClick1 button2 = new MouseClick1();

[...]

    public void Simulate_button1and2_Click(object sender, EventArgs e)
    {

       button1.CoordX = 1652;   //random coordinates
       button1.CoordY = 225;
       button2.CoordX = 1650;
       button2.CoordY = 250;

       button1.Click1();
       button1.Click2();

} }

To have the coordinates on your pointer, I use a timer and a label:

 private void timer1_Tick(object sender, EventArgs e)
        {
            Coord.Text = Cursor.Position.X.ToString() + " : " + Cursor.Position.Y.ToString();  //Premet d'avoir les coord en direct

        }

Work fine with me.

1 Comment

In your code button1.Click2(); should be button2.Click1();.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.