V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
daiv
V2EX  ›  Windows

如何控制 Windows 窗口程序 和 获取对应数据? (没有接口, 也没有继续开发的情况下)

  •  
  •   daiv · 189 天前 · 1275 次点击
    这是一个创建于 189 天前的主题,其中的信息可能已经有所发展或是发生改变。

    场景

    • 一个 Windows 窗口程序, 可能是 C# WinForm 开发的 (类似下图这样的窗口)
    • 没有接口, 也没有后续开发了, 但是一定要用这个自带的软件去控制一些特定的硬件
    • 为了无人值守的测试和控制, 记录测试数据, 想到用程序去控制这个窗口程序这种方式.

    需求

    • 按下图举例, 需要实现操作窗口和读取一些结果数据
      • 在 1 位置: 选择
      • 在 2 位置: 点击
      • 在 3 位置: 下拉后, 获取菜单信息并选择
      • 在 4 位置: 获取数据 (一些字符串, 一些数值等)
    • 优选 Golang/Python, 次选其他

    谢谢大家的回复

    image.png

    22 条回复    2023-10-23 15:41:35 +08:00
    x86
        1
    x86  
       189 天前
    按键精灵简单粗暴
    ysc3839
        2
    ysc3839  
       189 天前 via Android   ❤️ 1
    看上去是很标准的 Win32 控件,应该不难。主要难点大概是获取第一步 ListView 中项目的文字,应该是得在目标进程中分配内存。
    大致步骤是:
    找到左侧窗口的句柄。
    找到 ListView 的句柄。
    在目标进程分配内存 (VirtualAllocEx),发送消息读取项目名称到刚分配的内存中 (LVM_GETITEMTEXT),读取内存数据到自己进程中 (ReadProcessMemory),释放内存 (VirtualFreeEx)。找到对应条目,发送消息直接选中 (LVM_SETITEMSTATE)。
    找到 2 按钮的句柄,发送消息模拟点击。
    找到右侧窗口的句柄。
    找到 3ComboBox 的句柄。发送消息选中包含指定文字的项目 (CB_SELECTSTRING ,大概也需要像上面那样分配内存)。
    找到 4 标签的句柄,读取文本。
    查找顶级窗口句柄可以用 FindWindow ,传入标题和类名即可,类名可以用 Spy++查看。
    查找子控件句柄的话,一般子控件都会编号的,可以用 GetDlgItem 获取,编号可以用 Spy++查看。有编号的话,按钮大概也不需要模拟点击了,可以给父窗口发 WM_COMMAND 直接触发操作。
    ysc3839
        3
    ysc3839  
       189 天前 via Android
    不太建议用 Golang/Python ,因为系统 API 以及相关常量需要自己声明,用 C++写非常简单快捷。
    daiv
        4
    daiv  
    OP
       189 天前
    @x86 按键精灵可以完全做到?晚点我试试,对按键精灵停留在比较简单的操作
    daiv
        5
    daiv  
    OP
       189 天前
    @ysc3839 感谢你这么专业详细的回复,有可能付费请你写一部分吗? 我自己平时比较多写 Go 。 如果可以如何联系?
    ShineyWang
        6
    ShineyWang  
       189 天前 via Android   ❤️ 1
    不妨试试 powerautomate
    微软出品,原生控件应该能直接识别
    lonewolfakela
        7
    lonewolfakela  
       189 天前   ❤️ 1
    如果真的是 c# winform 的话,应该考虑能不能用反编译器直接把源码弄出来。如果工具本身没有特地做代码混淆的话,反编译出来的代码质量应该相当好,可以直接用。
    imicksoft
        8
    imicksoft  
       189 天前   ❤️ 1
    下载一个彗星助手,抓取一下那些界面控件,如果能单独抓取到,用易或 aardio 开发一个模拟操作软件就行了。
    ysc3839
        9
    ysc3839  
       189 天前 via Android
    @daiv 不接单,但如果你能提供相关信息(如窗口类名、控件 ID)的话,我可以免费写一些 C++的代码片段
    akira
        10
    akira  
       189 天前   ❤️ 1
    识别和点击 操作这些都不难,都是标准的 windows 跨进程操作,用键盘鼠标模拟或者消息模拟都可以。
    但是看到你似乎是涉及到硬件啥的,这种涉及到的逻辑情况就很麻烦了。
    404neko
        11
    404neko  
       189 天前   ❤️ 2
    看了一下没啥难度, 都是标准控件
    pywin32 应该够了

    https://free.wzznft.com/i/2023/10/21/ndk1ag.png
    ysc3839
        12
    ysc3839  
       189 天前 via Android
    另外我想问一下原始需求是什么?只是为了自动调整打印方向和获取固件版本吗?
    去查了一下,这个打印机可以用 ZPL 命令进行控制,也许可以直接控制,不需要通过操作配置软件的方式?
    daiv
        13
    daiv  
    OP
       189 天前
    @lonewolfakela 反编译这条路, 平时不玩这个, 时间成本有点高吧

    @imicksoft 晚点我试试彗星助手, 看起来应该能用得上.

    @akira 不会涉及到硬件部分, 是原有这套软件会去控制硬件, 我这次只是去尝试控制这个软件界面

    @404neko 看来大家有一个关注点都是 标准控件, 那我先要看看 目标窗口是不是都用标准控件了. (看到你还下载了 zebra 的软件来尝试, 谢谢, 其实我只是用 zebra 来做 demo )

    @ysc3839 #12 截图的 zebra 的软件截图是为了 演示, 不是目标软件.
    daiv
        14
    daiv  
    OP
       189 天前
    @ysc3839 #12 那我准备好 相关信息(如窗口类名、控件 ID), 然后辛苦你帮我写个示例, 详细的我自己来
    lonewolfakela
        15
    lonewolfakela  
       189 天前   ❤️ 1
    @daiv #13 没混淆的.Net 软件的反编译就是用 ILSpy 一键导出的事儿,超级简单……
    daiv
        16
    daiv  
    OP
       189 天前
    @lonewolfakela #15 .Net 不熟悉, 如果可以导出, 难道直接改源码?
    forgottencoast
        17
    forgottencoast  
       189 天前   ❤️ 1
    @daiv
    不要改,直接写个.Net 程序调用对方的窗体,然后操作或者获取值。
    我之前帮别人做过类似的事情。
    lonewolfakela
        18
    lonewolfakela  
       188 天前   ❤️ 1
    @daiv #16 如果发现它的源码不复杂的话直接改源码也可以。
    ysc3839
        19
    ysc3839  
       188 天前 via Android
    @daiv 那目标软件是什么呢?能提供相关信息吗?
    R0n1n
        20
    R0n1n  
       188 天前 via Android   ❤️ 1
    标准 Win 窗体控件,AutoIt3 很适合干这种事
    daiv
        21
    daiv  
    OP
       188 天前
    @R0n1n 感谢,我也去了解一下 autoit
    daiv
        22
    daiv  
    OP
       187 天前
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2672 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 36ms · UTC 11:15 · PVG 19:15 · LAX 04:15 · JFK 07:15
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.