xtdamo 是一个基于大漠插件(Dm) 的现代化封装库,用于自动化操作,包括窗口管理、鼠标控制、键盘模拟、图像识别、文本查找等功能。适用于游戏脚本、自动化测试、RPA 等场景。
- 分层架构: 清晰的
DmExcute -> ApiProxy -> CoreEngine三层设计 - 智能路由: 自动选择最佳方法实现,无需关心底层细节
- 模块化:
Key、Mouse独立模块,职责明确 - 向后兼容: 支持旧版本代码无缝迁移
- 参数验证: 完整的参数范围检查和类型验证
- 友好错误: 详细的错误信息和诊断建议
- 异常安全: 完善的异常处理机制
- Google Style: 所有方法都有详细的文档字符串
- 类型注解: 完整的类型提示,IDE 智能提示友好
- 示例丰富: 每个功能都有实用的代码示例
- 安全点击:
safe_click带随机延迟,防检测 - 便利属性:
position属性快速获取/设置鼠标位置 - 高级操作: 支持持续时间的点击、拖拽等复杂操作
xtdamo 提供了对大漠插件的高级封装,简化了与窗口、鼠标、键盘和图像识别相关的操作。主要功能包括:
- 窗口管理: 窗口查找、绑定、属性获取
- 鼠标操作: 移动、点击、拖拽、滚轮
- 键盘模拟: 按键、组合键、文本输入
- 图像识别: 图像查找、颜色识别
- 文本识别: 文字查找、OCR
- 高级功能: 文件操作、注册表操作
- Python 3.8+ (32 位版本) - 大漠插件仅支持 32 位 Python 环境
- Windows 操作系统
- 大漠插件(dm.dll)
重要提示: 大漠插件只能在 32 位 Python 环境下运行,请确保使用 32 位 Python 版本。
- 创建 32 位 Python 虚拟环境:
# 确保使用32位Python创建虚拟环境
python -m venv .venv --python=python3.12-32 # 或指定32位Python路径
.venv\Scripts\activate # Windows- 从源码安装:
git clone https://github.com/sandorn/xtdamo.git
cd xtdamo
pip install -e .- 从 PyPI 安装(计划中):
pip install xtdamo注意: 请确保在 32 位 Python 环境中安装和运行项目。
将大漠插件(dm.dll)放置在项目目录中,或通过环境变量指定路径:
# 设置大漠插件认证信息(可选)
set DM_REG_CODE=your_registration_code
set DM_VER_INFO=your_version_infoxtdamo 采用清晰的分层架构设计,确保代码的可维护性和可扩展性:
┌─────────────────────────────────────┐
│ DmExcute (主入口) │
│ - 统一的调用接口 │
│ - 自动方法路由 │
└──────────────┬──────────────────────┘
│
├──────────────────────┐
│ │
┌───────▼────────┐ ┌───────▼────────┐
│ ApiProxy │ │ CoreEngine │
│ (高级接口层) │───>│ (核心引擎层) │
│ │ │ │
│ - 中文友好API │ │ - 底层核心方法 │
│ - 智能错误处理 │ │ - 直接封装DM │
│ - 自动日志记录 │ │ - 基础功能实现 │
└────────────────┘ └────────────────┘
- 分层架构: 清晰的层次划分,职责明确
- 智能路由: 自动选择最合适的实现方法
- 向后兼容: 保持对旧代码的兼容性
- 易于扩展: 模块化设计,方便功能扩展
更多架构细节请参考 架构更新说明。
from xtdamo import DmExcute
# 初始化(自动注册大漠插件)
dm = DmExcute()
# 查看版本信息
print(f"版本: {dm.ver()}")
print(f"库版本: {dm.__version__}") # 输出: 0.2.0# 查找窗口
hwnd = dm.FindWindow("", "记事本")
if hwnd == 0:
print("未找到窗口")
exit(1)
# 绑定窗口(高级接口,带参数验证)
try:
dm.绑定窗口(
hwnd,
display='gdi', # 显示模式
mouse='windows3', # 鼠标模式
keypad='windows', # 键盘模式
mode=101 # 绑定模式
)
print("绑定成功!")
except ValueError as e:
print(f"参数错误: {e}")
except AssertionError as e:
print(f"绑定失败: {e}")
# 使用默认配置绑定(推荐)
dm.绑定窗口(hwnd) # 使用默认参数# 方式1: 通过 DmExcute 主入口(自动路由)
dm.MoveTo(100, 200) # 移动鼠标
dm.LeftClick() # 左键点击
# 方式2: 使用便利属性
x, y = dm.Mouse.position # 获取当前位置
dm.Mouse.position = (500, 300) # 设置位置
# 方式3: 使用增强方法
dm.Mouse.safe_click(300, 400, auto_reset_pos=True) # 安全点击
dm.Mouse.click_left(100, 200, t=1.0) # 长按1秒
# 方式4: 拖拽操作
dm.Mouse.MoveTo(100, 100)
dm.Mouse.LeftDown()
dm.Mouse.MoveTo(200, 200)
dm.Mouse.LeftUp()# 通过 DmExcute 主入口
dm.KeyPressStr('Hello World') # 输入文本
dm.KeyPress(13) # 按回车键(VK_RETURN)
# 使用 VirtualKeys 常量
from xtdamo.time_utils import VirtualKeys
dm.Key.KeyPress(VirtualKeys.ENTER)
dm.Key.KeyPress(VirtualKeys.ESC)
# 组合键操作
dm.Key.KeyDown(VirtualKeys.CTRL) # 按下Ctrl
dm.Key.KeyPress(ord('C')) # 按C键
dm.Key.KeyUp(VirtualKeys.CTRL) # 释放Ctrl
# 等待按键
if dm.Key.WaitKey(VirtualKeys.ESC, 5000):
print("用户按下了ESC键")# 高级接口 - 找图并点击
success = dm.找图单击(0, 0, 1920, 1080, 'button.bmp', '000000', 0.9)
if success:
print("找到并点击成功")
# 找图直到消失
dm.找图单击至消失(0, 0, 800, 600, 'close.bmp', max_retries=10)
# 获取坐标
found, x, y = dm.找图返回坐标(0, 0, 1920, 1080, 'target.bmp')
if found:
print(f"图像位置: ({x}, {y})")
dm.Mouse.safe_click(x, y)# 找字并点击
success = dm.找字单击(0, 0, 800, 600, '开始游戏', 'FFFFFF', 0.9)
# 简易识字
text = dm.简易识字(100, 100, 300, 200, 'FFFFFF', 0.9)
print(f"识别到的文字: {text}")
# 找字返回坐标
found, x, y = dm.找字返回坐标(0, 0, 800, 600, '确定', 'FFFFFF', 0.9)
if found:
dm.Mouse.MoveTo(x, y)
dm.Mouse.LeftClick()# 从中心点向外螺旋查找鼠标
found, x, y = dm.圆形渐开找鼠标(
center_x=500,
center_y=400,
max_radius=200,
pic_name='cursor.bmp'
)
if found:
print(f"鼠标图片位置: ({x}, {y})")from xtdamo import DmExcute
from xtdamo.time_utils import sleep, VirtualKeys
def main():
# 初始化
dm = DmExcute()
print(f"xtdamo 版本: {dm.__version__}")
# 查找并绑定窗口
hwnd = dm.FindWindow("", "目标程序")
if hwnd == 0:
print("未找到窗口")
return
# 绑定窗口(使用默认配置)
dm.绑定窗口(hwnd)
print("窗口绑定成功")
# 执行自动化任务
try:
# 点击开始按钮
if dm.找图单击(0, 0, 800, 600, 'start_button.bmp'):
print("点击开始按钮成功")
sleep(1)
# 输入用户名
dm.KeyPressStr('username')
dm.KeyPress(VirtualKeys.TAB)
# 输入密码
dm.KeyPressStr('password')
dm.KeyPress(VirtualKeys.ENTER)
# 等待登录完成(找图确认)
sleep(2)
if dm.简易找图(0, 0, 800, 600, 'login_success.bmp'):
print("登录成功!")
finally:
# 解绑窗口
dm.解绑窗口()
print("窗口已解绑")
if __name__ == '__main__':
main()欢迎贡献代码或提出建议!请参考 贡献指南 获取更多信息。
本项目遵循 MIT 许可证。