Python&按键精灵自动化

最近在项目中需要进行软件的自动化操作。

本博文以两种方式介绍如何自动化打开软件(Windows下),对其进行最大化最小化关闭等操作。


Python操作:

第一次接触自动化。相对比较熟悉Python自然是希望通过Python来操作软件。一般来说,通过程序来操作软件需要获得该软件的句柄,然后通过该句柄给软件发消息来操作该软件。Python中你需要安装Pywin32模块,该模块提供了访问Windows API的扩展,利用该模块你可以很方便的进行相关软件的操作。

这里先介绍一篇博文,如何利用Python和win32减少体力活,这篇博文介绍了pywin32模块,同时,介绍了很多有用的操作,如如何获取菜单句柄,下拉栏句柄,如何发送消息等。有更多的需要可以学习这篇博文,我这里只介绍如何通过pywin32打开软件,最大化,最小化,关闭等基本的操作。

首先是如何打开软件。

第一种方式,也是最简单的方式,利用os模块。比如我想打开记事本程序,可以:

def runApp():
    os.system(u"C:\\Windows\\System32\\notepad.exe")


os.system(command)中的command即为要执行的命令,也可以附加运行参数。这种方式非常简单,但是它有个缺点,它是阻塞的,即程序运行到这里后要等执行的程序执行完成后才能继续向下运行(个人理解)。

第二种方式是使用win32api中的ShellExecute函数。

该函数是非阻塞的。同样是打开记事本程序,可以这样写:

def runApp():
    import win32api
    # 最后一个参数表示是窗口属性,0表示不显示,1表示正常显示,2表示最小化,3表示最大化
    res = win32api.ShellExecute(0, 'open', 'C:\\Windows\\System32\\notepad.exe', '', '', 3)

其他方式:还有使用win32process中的CreateProcess方法和使用ctypes等方式,我这里没有用到,继续学习可以看博文: Python调用(运行)外部程序

接着,是获取软件的句柄。

打开软件后,对于窗口程序可以获取窗口句柄。句柄的获得对于后续操作至关重要。

比如我们打开了一个名叫233.txt的记事本程序,想获得它的句柄可以这样:

def findAppHandle():
    appName = u"233.txt - 记事本"
    hwnd = win32gui.FindWindow(None, appName)
    print hwnd

接着是通过句柄操作软件,给软件发消息:

比如想最大化软件,将软件窗口置于最前,关闭软件:

# 关闭软件
win32gui.PostMessage(hwnd, win32con.WM_CLOSE, 0, 0)
# 软件最大化
win32gui.PostMessage(hwnd, win32con.WM_SYSCOMMAND, win32con.SC_MAXIMIZE, 0)
# 将软件窗口置于最前
win32gui.SetForegroundWindow(hwnd)

这里面涉及到很多Windows的消息类型和参数,具体需要查阅MSDN。


按键精灵方式:

事实上,自动化软件在大部分情况下还有更方便的工具,那就是使用按键精灵。我这个项目所要自动化的软件中的很多的窗口句柄和操作很难通过程序来直接操作,于是,我又花了一点时间和同伴学了下按键精灵。

按键精灵是一款模拟鼠标键盘动作的软件。软件通过各种鼠标点定位,屏幕坐标或区域取色找色,键盘时间模拟,窗口句柄操作等等一系列强大的操作能够帮助实现各类软件自动化,游戏自动脚本等功能。而且精灵脚本可以进行编程制作,对于学过编程的人来说更容易(没学过也很简单)。

下面我提供一段代码,可以实现,精灵检测一个名叫记事本.txt的程序有没有打开,如果没有打开那么则打开F盘中的记事本.txt,并对该记事本.txt进行最大化,最小化,恢复窗口,向编辑窗口中写入一段话,关闭程序等操作。

// 搜索“记事本.txt - 记事本”,找到返回该程序句柄,否则返回空白
HwndEx = Plugin.Window.Search("记事本.txt - 记事本")
MyArray = Split(HwndEx, "|")
// 如果程序已经打开了
If UBound(MyArray)>=0 Then 
	Delay 50
	// 按照窗口名查找“记事本.txt - 记事本”,并返回该程序的句柄,如果没找到,则返回0
	Hwnd = Plugin.Window.Find(0, "记事本.txt - 记事本")
	Delay 2000
	// 获取记事本的编辑窗口句柄
	HwndEx = Plugin.Window.FindEx(Hwnd, 0, "Edit", 0)
	Call Plugin.Window.Max(Hwnd)
	Delay 2000
	Call Plugin.Window.Min(Hwnd)
	Delay 2000
	Call Plugin.Window.Restore(Hwnd)
	Delay 2000
	Call Plugin.Window.SendString(HwndEx, "www.baidu.com")
	Delay 2000
	Call Plugin.Window.Close(Hwnd)
	Delay 2000
Else  //如果软件没有打开,那么则打开该软件
	RunApp "F:\记事本.txt"
	Delay 2000
	Hwnd = Plugin.Window.Find(0, "记事本.txt - 记事本")
	Delay 2000
	HwndEx = Plugin.Window.FindEx(Hwnd, 0, "Edit", 0)
	Call Plugin.Window.Max(Hwnd)
	Delay 2000
	Call Plugin.Window.Min(Hwnd)
	Delay 2000
	Call Plugin.Window.Restore(Hwnd)
	Delay 2000
	Call Plugin.Window.SendString(HwndEx, "www.baidu.com")
	Delay 2000
	Call Plugin.Window.Close(Hwnd)
	Delay 2000
End If

按键精灵的脚本可以导出为exe文件,可以直接供调用和运行。


实际操作的情况往往比较复杂,在我的项目里,我用了Python脚本来模拟和管理要自动化的软件的运行环境,调用按键精灵的exe文件来实现整个软件的自动化。

### PyAutoGUI 实现鼠标按键自动化 #### 导入模块并初始化安全机制 为了确保在执行自动化过程中可以随时终止程序,建议启用PyAutoGUI的安全失败保护功能。这允许用户通过将鼠标移至屏幕左上角来立即停止任何正在进行的操作。 ```python import pyautogui pyautogui.FAILSAFE = True # 启用Failsafe机制[^4] ``` #### 基础鼠标操作 下面是一个简单的例子展示如何利用`pyautogui`来进行基本的鼠标动作,比如移动到指定位置以及模拟点击行为: ```python def perform_basic_mouse_actions(): position_x, position_y = (100, 100) # 定义目标坐标的X轴和Y轴数值 pyautogui.moveTo(position_x, position_y, duration=0.5) # 移动鼠标指针到(x,y),duration参数定义动画时间长度 pyautogui.click(button='left') # 执行一次左键单击操作[^2] perform_basic_mouse_actions() ``` #### 获取当前屏幕尺寸 了解显示器的实际分辨率对于准确定位元素至关重要。可以通过以下方式查询系统的屏幕大小: ```python screen_width, screen_height = pyautogui.size() # 返回一个元组形式表示宽度与高度 print(f'Screen resolution is {screen_width}x{screen_height}') # 输出屏幕解析度信息 ``` #### 创建更复杂的交互流程 除了基础的功能外,还可以构建更加复杂的应用场景,如响应特定热键组合启动或暂停任务、编写完整的自动化测试套件或是辅助性质的小工具等[^3]。 例如,这里有一个简单版本的任务调度器概念验证代码片段,它能够监听全局快捷键,并据此触发不同的处理逻辑: ```python from pynput.keyboard import Listener as KeyboardListener import threading class TaskScheduler: def __init__(self): self.running = False def start_task(self): print('Task started.') while self.running: pass # 这里放置实际的工作负载 def stop_task(self): print('Task stopped.') self.running = False def toggle_state(self, key=None): if not hasattr(key, 'char'): return char_lower = str.lower(getattr(key, 'char', '')) if char_lower == 'a' and self.running: self.stop_task() elif char_lower == 's': self.running = True thread = threading.Thread(target=self.start_task) thread.daemon = True thread.start() scheduler = TaskScheduler() with KeyboardListener(on_press=scheduler.toggle_state) as listener: try: listener.join() except KeyboardInterrupt: scheduler.stop_task() ``` 此段代码展示了怎样结合`pynput`库捕捉键盘事件,并依据这些输入改变内部状态以控制后台线程的行为模式。请注意,这段代码仅作为一个教学案例存在;真实环境中应当考虑更多细节因素,像多线程同步问题、异常捕获等等。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值