【问题标题】:Control another application using C#使用 C# 控制另一个应用程序
【发布时间】:2026-01-15 22:05:02
【问题描述】:

我需要通过模拟鼠标移动和键盘输入来控制其他应用程序。我如何在 C# 中实现这一点?甚至可能吗?

【问题讨论】:

标签: c# winforms


【解决方案1】:

你看过WhiteTestStack吗?

示例代码:

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

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

我认为没有比这更好的了。该库由 ThoughtWorks 创建。

【讨论】:

  • 我试图浏览 White 项目的文档,但它开始出现错误!顺便说一句,“白色”将为您提供 OO 方法来控制基于 Windows 的应用程序。
  • 我正在尝试访问 Spotify(一个音乐程序)并单击播放按钮,但它似乎是完全图形化的,因为我找不到任何句柄或任何带有 spy++ 的东西。我该怎么做?
  • @PontusMagnusson 您是否以某种方式管理它?我和你有同样的问题。
  • @Twenty 我做了,但不幸的是我没有代码了。我相信我将 Windows 事件排队以控制应用程序的不同元素。今天我想我会使用 Spotify API。
【解决方案2】:

请参阅此页面上的“将击键发送到其他应用程序”:

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

【讨论】:

    【解决方案3】:

    您可以使用 p/invoke,我窃取了以下代码,用于在具有已知句柄的按钮上随机点击鼠标:

        [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); 
    

    【讨论】:

      【解决方案4】:

      您可以使用AutoIT,它是免费软件,它有一个可以导入C# (DllImport) 的dll 版本。它允许您在 C# 的另一个应用程序上单击控件、将字符串写入编辑框、进行组合框选择等。

      【讨论】:

        【解决方案5】:

        使用SendMessage 原生 Win32 API。 DllImport 这个方法来自 User32.dll。您可以使用此 API 发送键盘和鼠标消息

        【讨论】:

          【解决方案6】:

          我也尝试过这样做:为了使用鼠标,我使用了这个类

          (需加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);
          
                  }
          
              }
          

          在你的 form1 之后(假设名字是 form1)你可以

           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();
          

          } }

          为了在指针上显示坐标,我使用了计时器和标签:

           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
          
                  }
          

          和我一起好好工作。

          【讨论】:

          • 在你的代码中button1.Click2(); 应该是button2.Click1();
          最近更新 更多