c#获取句柄,并对第三方软件的输入框和按钮进行控制

这篇具有很好参考价值的文章主要介绍了c#获取句柄,并对第三方软件的输入框和按钮进行控制。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

刚学了没多久,还有很多地方没有理解到位,还请大家指正。

当程序运行起来,就会显示在任务管理器中,软件中的每个事件,比如按钮,文本框等一些控件,每个事件都会产生一个句柄,句柄就是这些事件的标识符。如果拿到句柄就可以自己写软件对第三方软件进行控制。同一个软件在不同的电脑中的句柄一般是不一样的,但是获取的过程都是一样的。只要在当前电脑上找到事件的标识符即可。

具体的窗口句柄的结构可以用微软的spy++查看,spy++可以在VS的工具里找到,也可以到安装目录下找到。

c# 获取进程句柄,c#,自动化,windows,开发语言

 c# 获取进程句柄,c#,自动化,windows,开发语言

 c# 获取进程句柄,c#,自动化,windows,开发语言

拖动这个标记到需要查看的控件上松开,即可显示当前事件的句柄,点击确定搜索,即可确定当前控件所在的窗口位置。

有时候软件打开了但是搜索失败,需要对spy++刷新,只要电脑进程变了,句柄列表没来得及更新,这时候就需要对spy++进行刷新。

有的软件不能获取具体控件的句柄,比如像微信、QQ这样的,只能获取一个顶层的窗口。像这样的,那就说明这种程序的控件其实是不存在的,是画出来的,这种程序叫做directui程序,只能模仿鼠标键盘操作。

不是说所有的窗口都支持spy++来抓取,一般是windows标准窗口才能获取控件句柄,以及发送消息等。

接下来就是寻找句柄:

我用的是VS2022,他可以根据自己写的代码自动添加using,不用人为的添加,所以在这里就省略using。

        [DllImport("User32.dll", EntryPoint = "FindWindow")]
        private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
        
        [DllImport("User32.dll", EntryPoint = "FindWindowEx")]
        private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter,         string lpClassName, string lpWindowName);

        [DllImport("User32.dll", EntryPoint = "SendMessage")]
        private static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, string     lParam);

这里声明了三个方法。

第一个是FindWindow,这个方法只能查找顶层窗口的句柄,不能查找子窗口。

第二个是FindWindowEx,这个方法是用来查找子窗口的。

第三个是SendMessage,这个方法可以向指定的文本框输入数据和字符,还可以点击按钮。

c# 获取进程句柄,c#,自动化,windows,开发语言

我是要获取Pronterface那个软件的句柄,具体控件为右下角文本框和Send按钮。

这个软件有很多层,而且都是Windows标准控件。

 private void button1_Click(object sender, EventArgs e)
        {
            IntPtr hwnd = FindWindow("wxWindowClassNR", "Pronterface");     //FindWindow只查找顶层窗口
            IntPtr htextbox = FindWindowEx(hwnd, IntPtr.Zero, "wxWindowClassNR", null);//(当前为第一层)IntPtr.Zero则表示获得第一个子窗口。第三个参数表示你需要找的子窗口的类型,第四个参数一般为null。
                                                                            //如果一个窗口中有两个文本框,那么可以用如下操作获得第二个文本框的句柄。
           // IntPtr htextbox2 = FindWindowEx(hwnd, htextbox, "EDIT", null);//填上次获得的句柄,可以得到下一个的句柄。
            IntPtr htextbox21= FindWindowEx(htextbox, IntPtr.Zero, "wxWindowClassNR", null);//第二层第一个窗口//没问题
            IntPtr htextbox22 = FindWindowEx(htextbox, htextbox21, "wxWindowClassNR", null);//第二层第二个窗口//没问题
            IntPtr htextbox31 = FindWindowEx(htextbox22, IntPtr.Zero, "wxWindowClassNR", null);//3.1没问题
            IntPtr htextbox32 = FindWindowEx(htextbox22, htextbox31, "wxWindowClassNR", null);//3.2没问题
            IntPtr htextbox41 = FindWindowEx(htextbox32, IntPtr.Zero, "wxWindowClassNR", null);//4.1//000A105E//659550
            
            IntPtr htextbox51 = FindWindowEx(htextbox41, IntPtr.Zero, "wxWindowClassNR", null);//5.1//0012101C//1183772
            IntPtr htextbox52 = FindWindowEx(htextbox41, htextbox51, "wxWindowClassNR", null);//5.2
            IntPtr htextbox61 = FindWindowEx(htextbox52, IntPtr.Zero, "wxWindowClassNR", null);//6.1
            IntPtr htextbox71 = FindWindowEx(htextbox61, IntPtr.Zero, "wxWindowClassNR", null);//7.1
            //8.1和8.2为目标,8.1为文本框,8.2为send按钮
            IntPtr htextbox81 = FindWindowEx(htextbox71, IntPtr.Zero, "Edit", null);//8.1
            IntPtr htextbox82= FindWindowEx(htextbox71, IntPtr.Zero, "Button", null);//8.2
           
       
            SendMessage(htextbox81, WM_SETTEXT, IntPtr.Zero, "123232");//发送消息
     
            SendMessage(htextbox82, WM_LBUTTONDOWN, IntPtr.Zero, null);//鼠标按下按钮
            SendMessage(htextbox82, WM_LBUTTONUP, IntPtr.Zero, null);//释放鼠标
            SendMessage(htextbox81, WM_INITDIALOG, IntPtr.Zero, null);
            SendMessage(htextbox81, WM_SETTEXT, IntPtr.Zero, "\t");//发送消息



        }
 IntPtr hwnd = FindWindow("wxWindowClassNR", "Pronterface"); 

第一行用了FindWindow方法,用来获取顶层窗口的句柄,获得到的句柄存在hwnd中,可以打印出来看结果,打印出来的是十进制的,spy++里看到的是十六进制的。FindWindow中的第一项是类名,第二项为窗口的标题,一般只用标题即可。下面这样写也可以。

IntPtr hwnd = FindWindow(null, "Pronterface"); 

接下来就是FindWindowEx方法,查找子窗口。

 IntPtr htextbox21= FindWindowEx(htextbox, IntPtr.Zero, "wxWindowClassNR", null);//第二层第一个窗口//没问题
 IntPtr htextbox22 = FindWindowEx(htextbox, htextbox21, "wxWindowClassNR", null);//第二层第二个窗口//没问题

FindWindowEx方法有四项,第一项是父级窗口的句柄,就是你想要在哪个大窗口下找。父级和子级是相对的,从外到里,就像剥洋葱,外面就是里面的父,而里面的窗口就是外面窗口的子。

第二项填的内容是个句柄。例如上面的两行代码,如果是IntPtr.Zero,那要找的窗口就是htextbox这个父级窗口下的第一个子窗口,如果是htextbox21,那么要找的窗口就是在htextbox这个父级窗口下,排在htextbox21的下面的一个窗口。以此类推。

第三项为要查找的控件的类名,可以在spy++上查找具体控件的类名

第四项为要查找的子窗口的名字,可以为null。

获取到了句柄值就可以对他们进行操作了。然后介绍SendMessage这个方法,这个方法有四个参数。

 SendMessage(htextbox81, WM_SETTEXT, IntPtr.Zero, "123232");//发送消息
 SendMessage(htextbox82, WM_LBUTTONDOWN, IntPtr.Zero, null);//鼠标按下按钮
 SendMessage(htextbox82, WM_LBUTTONUP, IntPtr.Zero, null);//释放鼠标
 SendMessage(htextbox81, WM_SETTEXT, IntPtr.Zero, "\t");//发送消息

第一个参数就是要操作的窗口的句柄,第二项就是要操作什么,不同的值会产生不同的操作。第三项一般为IntPtr.Zero。第四项一般为null,如果是向文本框发送消息,那么第四项就是要发送的字符。

第二项的参数需要提前定义,具体完整的指令表需要去查,这里只提供了一些:

    const int WM_INITDIALOG = 0x0110;//初始化
    const int WM_SETTEXT = 0x000C;//发送消息
    const int WM_LBUTTONDOWN = 0x0201;//按下鼠标左键 
    const int WM_LBUTTONUP = 0x0202;//释放鼠标左键
    const int WM_LBUTTONDBLCLK = 0x203; //双击鼠标左键
    const int WM_RBUTTONDOWN = 0x204;//按下鼠标右键
    const int WM_RBUTTONUP = 0x205;//释放鼠标右键
    const int WM_RBUTTONDBLCLK = 0x206;//双击鼠标右键

这个第二项有点类似于单片机寄存器的值,设置不同的值,会有不同的功能。

我是控制的一个名字为Pronterface的软件,建的winform程序,添加了一个按钮,和两个文本框,文本框用来测试获取的句柄是否正确。然后附上完整代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Diagnostics;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using System.Xml.Linq;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.ToolBar;

namespace WindowsFormsApp28
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        [DllImport("User32.dll", EntryPoint = "FindWindow")]
        private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
        [DllImport("User32.dll", EntryPoint = "FindWindowEx")]
        private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpClassName, string lpWindowName);

        [DllImport("User32.dll", EntryPoint = "SendMessage")]
        private static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, string lParam);



        //分隔符,以下几个常量放入事件中可用


        const int WM_INITDIALOG = 0x0110;//初始化
        const int WM_SETTEXT = 0x000C;
        const int WM_LBUTTONDOWN = 0x0201;//按下鼠标左键 
        const int WM_LBUTTONUP = 0x0202;//释放鼠标左键
        const int WM_CLOSE = 0x0010;
        const int WM_LBUTTONDBLCLK = 0x203; //双击鼠标左键
        const int WM_RBUTTONDOWN = 0x204;//按下鼠标右键
        const int WM_RBUTTONUP = 0x205;//释放鼠标右键
        const int WM_RBUTTONDBLCLK = 0x206;//双击鼠标右键




        private void button1_Click(object sender, EventArgs e)
        {
            IntPtr hwnd = FindWindow("wxWindowClassNR", "Pronterface");     //FindWindow只查找顶层窗口
            IntPtr htextbox = FindWindowEx(hwnd, IntPtr.Zero, "wxWindowClassNR", null);//(当前为第一层)IntPtr.Zero则表示获得第一个子窗口。第三个参数表示你需要找的子窗口的类型,第四个参数一般为null。
                                                                            //如果一个窗口中有两个文本框,那么可以用如下操作获得第二个文本框的句柄。
           // IntPtr htextbox2 = FindWindowEx(hwnd, htextbox, "EDIT", null);//填上次获得的句柄,可以得到下一个的句柄。
            IntPtr htextbox21= FindWindowEx(htextbox, IntPtr.Zero, "wxWindowClassNR", null);//第二层第一个窗口//没问题
            IntPtr htextbox22 = FindWindowEx(htextbox, htextbox21, "wxWindowClassNR", null);//第二层第二个窗口//没问题
            IntPtr htextbox31 = FindWindowEx(htextbox22, IntPtr.Zero, "wxWindowClassNR", null);//3.1没问题
            IntPtr htextbox32 = FindWindowEx(htextbox22, htextbox31, "wxWindowClassNR", null);//3.2没问题
            IntPtr htextbox41 = FindWindowEx(htextbox32, IntPtr.Zero, "wxWindowClassNR", null);//4.1//000A105E//659550
            
            IntPtr htextbox51 = FindWindowEx(htextbox41, IntPtr.Zero, "wxWindowClassNR", null);//5.1//0012101C//1183772
            IntPtr htextbox52 = FindWindowEx(htextbox41, htextbox51, "wxWindowClassNR", null);//5.2
            IntPtr htextbox61 = FindWindowEx(htextbox52, IntPtr.Zero, "wxWindowClassNR", null);//6.1
            IntPtr htextbox71 = FindWindowEx(htextbox61, IntPtr.Zero, "wxWindowClassNR", null);//7.1
            //8.1和8.2为目标,8.1为文本框,8.2为send按钮
            IntPtr htextbox81 = FindWindowEx(htextbox71, IntPtr.Zero, "Edit", null);//8.1
            IntPtr htextbox82= FindWindowEx(htextbox71, IntPtr.Zero, "Button", null);//8.2
            textBox1.Text = (""+htextbox81);

            textBox2.Text = ("" + htextbox82);
       
            SendMessage(htextbox81, WM_SETTEXT, IntPtr.Zero, "123232");//发送消息
     
            SendMessage(htextbox82, WM_LBUTTONDOWN, IntPtr.Zero, null);//鼠标按下按钮
            SendMessage(htextbox82, WM_LBUTTONUP, IntPtr.Zero, null);//释放鼠标
            SendMessage(htextbox81, WM_INITDIALOG, IntPtr.Zero, null);
            SendMessage(htextbox81, WM_SETTEXT, IntPtr.Zero, "\t");//发送消息

        }




    }
}

c# 获取进程句柄,c#,自动化,windows,开发语言文章来源地址https://www.toymoban.com/news/detail-596477.html

到了这里,关于c#获取句柄,并对第三方软件的输入框和按钮进行控制的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android 11以上获取不到第三方app是否安装

    开年第一篇,处理了一下年前的小问题。 问题:本地app跳转到第三方app地图进行导航,获取不到第三方地图是否安装。 解决: 1.添加包名  This can be done by adding a  queries  element in the Android manifest.在app下的manifest文件内manifest标签下添加 queries标签设置包名 2.MapUtil工具类 3.调用

    2024年02月19日
    浏览(57)
  • C#使用第三方库ExcelDataReader读取excel数据并呈现

    之前有使用Oledb读取Excel的代码:C#读取excel数据并呈现 使用这种方式读取存在需要安装数据库引擎的隐患(如需要自取)

    2024年02月13日
    浏览(44)
  • QT---将第三方软件窗口嵌入窗口中

    通过Windows API获取窗口句柄。 代码如下:

    2024年02月12日
    浏览(79)
  • 通过第三方软件修改 MacOS 的键盘映射

    由于文本编辑时大量使用word level的左移、右移,其中: OSX的单词级左右移为option + Left/Right Arrow,整行级左右移为command + Left/Right Arrow 单词级移动与进行编辑常用的command不同键位,因此尝试交换二者功能 由于 command 键在OSX下的其他重要作用,不方便直接将 option 与 command 进行

    2024年02月09日
    浏览(63)
  • 微信小程序获取当前位置与跳转第三方地图

    1. 先在app.json添加配置 2. 获取定位权限,打开地址选点 3. 如果要打开跳转第三方地图的内置地图

    2024年02月15日
    浏览(69)
  • 刷入twrp_twrp刷入面具&进入recovery(twrp)的方式&获取root&刷入第三方rom&获取第三方rom包&类原生rom包的网络连接受限问题

    以redmi 4x为例 下面的教程中,有些步骤不是必须要的,但是可以开阔思路 Install LineageOS on santoni | LineageOS Wiki Xiaomi Redmi 4X (twrp.me) Download and Install Lineage OS 19 for Redmi 4X (Android 12) (getdroidtips.com) 已经解锁的android手机(譬如小米/redmi手机) 解锁小米手机 - Magisk中文网 (magiskcn.com) 同时,在

    2024年02月08日
    浏览(66)
  • mac删不掉的软件怎么办 Mac怎么删除第三方软件?

    我们在使用Mac电脑的过程中,随着使用时间变长,下载安装的软件也会增多。我们不仅会在“App Store”里下载软件,也会在其他地方下载安装第三方软件。但是,有的朋友想要卸载删除这些软件时,却不清楚如何删除这些软件。在使用Mac电脑时,有时会遇到删除某些应用程序

    2024年02月03日
    浏览(63)
  • linux第三阶段--第三方软件(一)MySQL的概述和二进制安装(官网版)

    DB2 POSTGRE-SQL RDBMS(relational database management system),既关系型数据库管理系统。 简单来说,关系型数据库,是指采用了 二维表格 来组织数据的数据库。 扩展:数据库在行业内一般会有两种情况,关系型数据库与非关系型数据库。非关系型数据库并不是通过二维表格来维护数

    2024年02月12日
    浏览(55)
  • 泛微OA获取流程附件地址,发送邮件或上传到第三方系统中

    在泛微的流程开发当中,有些流程的数据、附件要上传到其它平台,与其它平台相互集成对接, 一般是在写Action事件时,就会自动把数据及附件上传到其它平台,以下内容是经过正常使用获取流程附件的业务 示例:泛微OA中流程附件

    2024年02月15日
    浏览(94)
  • 细思极恐,第三方跟踪器正在获取你的数据,如何防范?

    当下,许多网站都存在一些Web表单,比如登录、注册、评论等操作需要表单。我们都知道,我们在冲浪时在网站上键入的数据会被第三方跟踪器收集。 但是 ,你知道吗?第三方跟踪器甚至可在提交表单之前就获取你的数据。 来自 KU Leuven、Radboud 大学和洛桑大学的一个研究小

    2023年04月16日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包