简体   繁体   English

如何使用C#代码以编程方式单击运行应用程序中的按钮

[英]how to programmatically click on a button in running app using C# code

I want to write a C# program which will launch an .exe (this is an easy job, I know how to do it.) but now I want to add some more functionality to it. 我想写一个C#程序,它将启动一个.exe(这是一个简单的工作,我知道该怎么做。)但现在我想为它添加更多的功能。 I want to take user inputs to my program and want to pass them to running .exe as a input.Also I want to click on a particular button available on the exe window. 我想将用户输入传递给我的程序,并希望将它们作为输入传递给运行.exe。我还要单击exe窗口上的特定按钮。 Important thing is, I want to do it programatically without user knowledge that we are actually running that exe in background. 重要的是,我想以编程方式执行它,而不是用户知道我们实际上在后台运行该exe。 Please let me know if it is possible. 如果可能,请告诉我。 It is very urgent. 这非常紧迫。

Yes it is possible with Windows API. 是的,可以使用Windows API。 You need to send a message to that Window. 您需要向该窗口发送消息。 At first use Spy++ to get IDs of all buttons you want to click. 首先使用Spy ++获取要单击的所有按钮的ID。 Spy++ is a Visual Studio tool and it shows you what messages are being sent to the application when you press those buttons. Spy ++是一个Visual Studio工具,它会向您显示按下这些按钮时发送给应用程序的消息。 Then use PostMessage() function (Windows API) to send the same message programatically. 然后使用PostMessage()函数(Windows API)以编程方式发送相同的消息。

You can also for example look at Winamp (a music player for windows), there is documentation on how to press its buttons from external app. 您还可以查看Winamp(Windows的音乐播放器),有关于如何从外部应用程序按下其按钮的文档。 You can do it the same way for other apps, you just need to know IDs of all controls and names of windows or their classes. 您可以以相同的方式为其他应用程序执行此操作,您只需要知道所有控件的ID以及窗口或其类的名称。

here is code to click on Winamp's pause button: 这是代码点击Winamp的暂停按钮:

#define AMP_PAUSE 40046
HWND hwnd = FindWindow("Winamp v1.x", 0);
if(hwnd) SendMessage(hwnd, WM_COMMAND, AMP_PAUSE, 0);

This is written in C++. 这是用C ++编写的。 If you do it in C#, use PInvoke to get access to Windows API. 如果您在C#中执行此操作,请使用PInvoke来访问Windows API。 I assume you know how to do this. 我假设你知道怎么做。 In the first step FindWindow gets a handle to the window, it identifies it by the name of its class. 在第一步中,FindWindow获取窗口的句柄,它通过其类的名称来标识它。 Then we use SendMessage or PostMessage to send the message. 然后我们使用SendMessage或PostMessage发送消息。 There are four parameters: window to send the message to, message id, and two parameters. 有四个参数:发送消息的窗口,消息ID和两个参数。

In Spy++ you can find those parameters you need for FindWindow and SendMessage. 在Spy ++中,您可以找到FindWindow和SendMessage所需的参数。 Please start it and play with it a little bit to see what it can do. 请启动它并稍微玩一下,看它能做些什么。

If you want to avoid directly use of WIN API, there's a small library that can help you with this, WindowScrape . 如果你想避免直接使用WIN API,那么有一个小型库可以帮助你解决这个问题, WindowScrape

You can use it directly from C#. 您可以直接从C#使用它。 Some of the features: 一些功能:

  • Search for windows and child controls registered in memory. 搜索在内存中注册的窗口和子控件。
  • Change the titles of windows 更改窗口的标题
  • Change the text of UI elements (permissions/privacy permitting) 更改UI元素的文本(权限/隐私允许)
  • Click on UI elements 单击UI元素
  • Read the Titles of windows 阅读窗户的标题
  • Read the text from UI elements 从UI元素中读取文本
  • Navigate through object hierarchies 浏览对象层次结构
  • Set object locations 设置对象位置
  • Set object sizes 设置对象大小

There might be other similar libraries, but at this point this is the only one that i'm aware. 可能还有其他类似的库,但此时这是我唯一知道的库。

Edited 编辑

Sample Usage: 样品用法:

using System.Windows.Forms;

//WindowScrape
using WindowScrape.Types;

namespace WindowsFormsTestApplication
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            var npad = HwndObject.GetWindowByTitle("Untitled - Notepad");
        }
    }
}

如果是WPF应用程序,您可以查看AutomationPeers

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM