依星源码资源网,依星资源网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

【好消息,好消息,好消息】VIP会员可以发表文章赚积分啦 !
查看: 40|回复: 0

python spI命令 spy++ python

[复制链接] 主动推送

1万

主题

1万

帖子

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
11969
发表于 7 天前 | 显示全部楼层 |阅读模式
python spI命令 spy++ python
SPY++的使用和Python操作
1、spy++的基本操作
1.1 窗口属性查找
1.2 窗口spy++定位
2、python与spy++
Source Code
Use
下载 Spy++:VC6.0下面的spy++,小巧方便
1、spy++的基本操作

python spI命令 spy++ python

python spI命令 spy++ python

1.1 窗口属性查找

python spI命令 spy++ python

python spI命令 spy++ python


拖住中间的“寻找工具”放到想要定位的软件上,然后松开

python spI命令 spy++ python

python spI命令 spy++ python


以微信为例,我们会得到“微信”这个窗口的句柄,为“00031510”,注意这个句柄是“十六进制”,即“0x31510”。
点击ok我们会看到更详细的属性信息
1.2 窗口spy++定位

python spI命令 spy++ python

python spI命令 spy++ python


同理拖放到“微信”上,获取到“微信”的界面
点击ok,会直接定位到“微信”
在这里我们会看到一条信息
00031510 “微信” WeChatMainWndForPC
– 00031510:代表十六进制的窗口句柄
– 微信:代表窗口标题
– WeChatMainWndForPC:代表窗口的类名
2、python与spy++
Source Code
  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. # @Time   : 2021/1/27 10:50
  4. # @Author : SandQuant

  5. import collections
  6. from win32 import win32gui
  7. import pyautogui
  8. import sys


  9. class PySpy(object):
  10.     Window = collections.namedtuple('Window', ['caption', 'class_name', 'hwnd_py', 'hwnd_spy'])

  11.     def __init__(self):
  12.         pass

  13.     @classmethod
  14.     def window_attr(cls, hwnd_py):
  15.         """
  16.         显示窗口的属性
  17.         :param hwnd_py: 窗口句柄(十进制)
  18.         :return: Window
  19.         """
  20.         return cls.Window(
  21.             caption=win32gui.GetWindowText(hwnd_py),
  22.             class_name=win32gui.GetClassName(hwnd_py),
  23.             hwnd_py=hwnd_py,
  24.             hwnd_spy=hex(hwnd_py),
  25.         )

  26.     @classmethod
  27.     def show_top_windows(cls):
  28.         """
  29.         列出所有的顶级窗口及属性
  30.         :return: 全部的顶层窗口及对应属性
  31.         """
  32.         containers = []
  33.         win32gui.EnumWindows(lambda hwnd, param: param.append(cls.window_attr(hwnd)), containers)
  34.         return containers

  35.     @classmethod
  36.     def find_top_window(cls, caption) -> list:
  37.         """
  38.         查找窗体
  39.         :param caption: 窗口标题部分文字
  40.         :return:
  41.         """
  42.         return [w for w in cls.show_top_windows() if caption in w.caption]

  43.     @classmethod
  44.     def find_sub_windows(cls, hwnd_py=None, class_name=None, caption=None, index=None):
  45.         """
  46.         返回窗体下全部的子窗体,默认主窗体下的窗体
  47.         :param hwnd_py: 句柄 十进制
  48.         :param class_name: 窗口类名,返回特定类名
  49.         :param caption: 窗口标题,返回特定标题
  50.         :param index: 位置,返回特定位置的窗口
  51.         :return: 包含属性的全部子窗口
  52.         """
  53.         num = 0
  54.         handle = 0
  55.         sub_windows = []
  56.         while True:
  57.             # find next handle, return HwndPy
  58.             handle = win32gui.FindWindowEx(hwnd_py, handle, class_name, caption)
  59.             if handle == 0:
  60.                 # no more handle
  61.                 break
  62.             # get handle attribution
  63.             attr = cls.window_attr(handle)
  64.             # append to list
  65.             sub_windows.append(tuple(list(attr) + [num]))
  66.             num += 1
  67.         if index is not None:
  68.             return sub_windows[index]
  69.         else:
  70.             return sub_windows

  71.     @classmethod
  72.     def show_all_windows(cls, window=None, handle_list=None, handle_dict=None):
  73.         """
  74.         生成窗口全部对应的关系
  75.         :param window: 目标父窗口
  76.         :param handle_list: 默认为[[None]]
  77.         :param handle_dict: 用于存放对应关系
  78.         :return: 返回目标窗口下全部子父窗口的字典
  79.         """
  80.         if not handle_list and not handle_dict:
  81.             handle_list = [[None]]
  82.             handle_dict = dict()
  83.         sys.setrecursionlimit(1000000)
  84.         if window:
  85.             handle_list[-1][0] = window
  86.             handles = cls.find_sub_windows(handle_list[-1][0][2])
  87.         else:
  88.             handles = cls.find_sub_windows()
  89.         for handle in handles:
  90.             handle_dict[handle] = window
  91.         # 这个根节点已经遍历完,删除
  92.         del handle_list[-1][0]
  93.         # 如果有叶节点,非空,则加入新的叶节点
  94.         if handles:
  95.             handle_list.append(handles)
  96.         # 删除已被清空的根
  97.         handle_list = [HandleGroup for HandleGroup in handle_list if HandleGroup]
  98.         # 如果还有根就继续遍历,否则输出树
  99.         if handle_list:
  100.             return cls.show_all_windows(window=handle_list[-1][0], handle_list=handle_list, handle_dict=handle_dict)
  101.         else:
  102.             return handle_dict

  103.     @classmethod
  104.     def find_handle_path(cls, hwnd_spy, num):
  105.         """
  106.         寻找特定窗口的寻找路径
  107.         找到全部层级的对应关系,然后反向搜索
  108.         :param hwnd_spy: 窗口句柄(十六进制)
  109.         :param num: 窗口所属index,在spy++内查看
  110.         :return:
  111.         parent_window:顶层窗口
  112.         target_path:路径的index
  113.         """
  114.         all_path = cls.show_all_windows()
  115.         key = tuple(list(cls.window_attr(int(hwnd_spy))) + [num])
  116.         handle_path = [key]
  117.         while True:
  118.             key = all_path[key]
  119.             if not key:
  120.                 handle_path = handle_path[::-1]
  121.                 parent_window = handle_path[0]
  122.                 target_path = [(i[-1]) for i in handle_path[1:]]
  123.                 return parent_window, target_path
  124.             handle_path.append(key)

  125.     @classmethod
  126.     def find_target_handle(cls, window, path):
  127.         """
  128.         递归寻找子窗口的句柄
  129.         :param window: 祖父窗口的完整句柄 (WindowName, ClassName, HwndPy, HwndSpy)
  130.         :param path: 子窗口列表
  131.         :return: 目标窗口的完整属性
  132.         """
  133.         for i in range(len(path)):
  134.             window = cls.find_sub_windows(window[2], index=path[i])
  135.         return window
复制代码
Use
1、获取窗体属性



  1. # 获取句柄1902690的属性
  2. window = PySpy.window_attr(hwnd_py=1902690)
  3. print(window)
复制代码
  1. Window(caption='百度云', class_name='ATL:011386F8', hwnd_py=1902690, hwnd_spy='0x1d0862')
复制代码
2、获取全部顶层窗体
  1. # 获取全部顶层窗体
  2. windows = PySpy.show_top_windows()[:5]
  3. for w in windows:
  4.     print(w)
复制代码
  1. Window(caption='', class_name='ForegroundStaging', hwnd_py=66032, hwnd_spy='0x101f0')
  2. Window(caption='', class_name='ForegroundStaging', hwnd_py=65982, hwnd_spy='0x101be')
  3. Window(caption='', class_name='tooltips_class32', hwnd_py=65836, hwnd_spy='0x1012c')
  4. Window(caption='', class_name='tooltips_class32', hwnd_py=65844, hwnd_spy='0x10134')
  5. Window(caption='', class_name='tooltips_class32', hwnd_py=65856, hwnd_spy='0x10140')
复制代码
3、查找指定的顶层窗体
  1. # 查找顶层窗体
  2. result = PySpy.find_top_window(caption='spy++')
  3. print(result)
复制代码
  1. [Window(caption='spy++', class_name='CabinetWClass', hwnd_py=9571640, hwnd_spy='0x920d38')]
复制代码
4、查找特定父窗体下全部子窗体
  1. # 查找特定句柄下全部子窗体
  2. window = PySpy.find_sub_windows(hwnd_py=9571640)
  3. for w in windows:
  4.     print(w)
复制代码
  1. Window(caption='', class_name='ForegroundStaging', hwnd_py=66032, hwnd_spy='0x101f0')
  2. Window(caption='', class_name='ForegroundStaging', hwnd_py=65982, hwnd_spy='0x101be')
  3. Window(caption='', class_name='tooltips_class32', hwnd_py=65836, hwnd_spy='0x1012c')
  4. Window(caption='', class_name='tooltips_class32', hwnd_py=65844, hwnd_spy='0x10134')
  5. Window(caption='', class_name='tooltips_class32', hwnd_py=65856, hwnd_spy='0x10140')
复制代码
5、获取全部窗体父子对应关系
  1. # 生成窗口全部对应的关系
  2. windows = PySpy.show_all_windows(window=('spy++', 'CabinetWClass', 9571640, '0x920d38'))
  3. for w in windows.items():
  4.     print(w)
复制代码
  1. (('UIRibbonDockLeft', 'UIRibbonCommandBarDock', 1838390, '0x1c0d36', 0), ('spy++', 'CabinetWClass', 9571640, '0x920d38'))
  2. (('UIRibbonDockRight', 'UIRibbonCommandBarDock', 1773536, '0x1b0fe0', 1), ('spy++', 'CabinetWClass', 9571640, '0x920d38'))
  3. (('UIRibbonDockTop', 'UIRibbonCommandBarDock', 2756588, '0x2a0fec', 2), ('spy++', 'CabinetWClass', 9571640, '0x920d38'))
  4. ...
  5. (('', 'ScrollBar', 52956100, '0x3280bc4', 0), ('', 'CtrlNotifySink', 3607746, '0x370cc2', 1))
  6. (('', 'ReBarWindow32', 11603876, '0xb10fa4', 0), ('', 'WorkerW', 2755884, '0x2a0d2c', 1))
  7. (('', 'ToolbarWindow32', 2427436, '0x250a2c', 0), ('', 'ReBarWindow32', 11603876, '0xb10fa4', 0))
复制代码
6、获取特定窗体的查找路径
  1. # 寻找特定窗口的寻找路径
  2. parent, pth = PySpy.find_handle_path(hwnd_spy=0xb10fa4, num=0)
  3. print(parent, pth)
复制代码
  1. ('spy++', 'CabinetWClass', 9571640, '0x920d38', 232) [5, 1, 0]
复制代码
7、根据查找路径获取到句柄信息(6的逆过程)
  1. # 根据顶层窗体和路径 寻找子窗口的句柄
  2. window = PySpy.find_target_handle(window=parent, path=pth)
  3. print(window)
复制代码
  1. ('', 'ReBarWindow32', 11603876, '0xb10fa4', 0)
复制代码
8、根据窗体句柄,找到窗体位置
  1. # 根据句柄定位窗体
  2. x, y, m, n = win32gui.GetWindowRect(9571640)
  3. pyautogui.moveTo((x + m) / 2, (y + n) / 2)
复制代码



相关帖子

扫码关注微信公众号,及时获取最新资源信息!下载附件优惠VIP会员6折;永久VIP4折
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

免责声明:
1、本站提供的所有资源仅供参考学习使用,版权归原著所有,禁止下载本站资源参与商业和非法行为,请在24小时之内自行删除!
2、本站所有内容均由互联网收集整理、网友上传,并且以计算机技术研究交流为目的,仅供大家参考、学习,请勿任何商业目的与商业用途。
3、若您需要商业运营或用于其他商业活动,请您购买正版授权并合法使用。
4、论坛的所有内容都不保证其准确性,完整性,有效性,由于源码具有复制性,一经售出,概不退换。阅读本站内容因误导等因素而造成的损失本站不承担连带责任。
5、用户使用本网站必须遵守适用的法律法规,对于用户违法使用本站非法运营而引起的一切责任,由用户自行承担
6、本站所有资源来自互联网转载,版权归原著所有,用户访问和使用本站的条件是必须接受本站“免责声明”,如果不遵守,请勿访问或使用本网站
7、本站使用者因为违反本声明的规定而触犯中华人民共和国法律的,一切后果自己负责,本站不承担任何责任。
8、凡以任何方式登陆本网站或直接、间接使用本网站资料者,视为自愿接受本网站声明的约束。
9、本站以《2013 中华人民共和国计算机软件保护条例》第二章 “软件著作权” 第十七条为原则:为了学习和研究软件内含的设计思想和原理,通过安装、显示、传输或者存储软件等方式使用软件的,可以不经软件著作权人许可,不向其支付报酬。若有学员需要商用本站资源,请务必联系版权方购买正版授权!
10、本网站如无意中侵犯了某个企业或个人的知识产权,请来信【站长信箱312337667@qq.com】告之,本站将立即删除。
郑重声明:
本站所有资源仅供用户本地电脑学习源代码的内含设计思想和原理,禁止任何其他用途!
本站所有资源、教程来自互联网转载,仅供学习交流,不得商业运营资源,不确保资源完整性,图片和资源仅供参考,不提供任何技术服务。
本站资源仅供本地编辑研究学习参考,禁止未经资源商正版授权参与任何商业行为,违法行为!如需商业请购买各资源商正版授权
本站仅收集资源,提供用户自学研究使用,本站不存在私自接受协助用户架设游戏或资源,非法运营资源行为。
 
在线客服
点击这里给我发消息 点击这里给我发消息 点击这里给我发消息
售前咨询热线
312337667

微信扫一扫,私享最新原创实用干货

QQ|免责声明|小黑屋|依星资源网 ( 鲁ICP备2021043233号-3 )|网站地图

GMT+8, 2025-1-15 09:48

Powered by Net188.com X3.4

邮箱:312337667@qq.com 客服QQ:312337667(工作时间:9:00~21:00)

快速回复 返回顶部 返回列表