如何使用Python检测Windows系统是否空闲(即没有键盘或鼠标活动)。
这已经在之前被问过,但在pywin32
模块中似乎没有GetLastInputInfo
函数。
from ctypes import Structure, windll, c_uint, sizeof, byref
class LASTINPUTINFO(Structure):
_fields_ = [
('cbSize', c_uint),
('dwTime', c_uint),
]
def get_idle_duration():
lastInputInfo = LASTINPUTINFO()
lastInputInfo.cbSize = sizeof(lastInputInfo)
windll.user32.GetLastInputInfo(byref(lastInputInfo))
millis = windll.kernel32.GetTickCount() - lastInputInfo.dwTime
return millis / 1000.0
调用get_idle_duration()
以获取空闲时间(秒)。
windll.user32.GetLastInputInfo
上设置argtypes
、restype
或errcheck
,因此您应该使用自己的WinDLL
实例,例如 user32 = WinDLL('user32', use_last_error=True)
。 - Eryk Sunimport win32api
def getIdleTime():
return (win32api.GetTickCount() - win32api.GetLastInputInfo()) / 1000.0
看起来GetLastInputInfo
现在可在pywin32中使用:
win32api.GetLastInputInfo()
这个技巧可以返回用户上次输入操作的计时器滴答。
附带一个示例程序:
import time
import win32api
for i in range(10):
print(win32api.GetLastInputInfo())
time.sleep(1)
如果在脚本休眠时按键/移动鼠标,打印的数字会发生改变。@FogleBird的回答很棒且有效,但在匆忙中我不确定它是如何工作的,所以这里提供一个小测试示例。一个线程正在启动,每10秒钟查找上一次空闲时间。如果在此时间窗口内进行任何移动,它将被打印出来。
from ctypes import Structure, windll, c_uint, sizeof, byref
import threading
//Print out every n seconds the idle time, when moving mouse, this should be < 10
def printit():
threading.Timer(10.0, printit).start()
print get_idle_duration()
class LASTINPUTINFO(Structure):
_fields_ = [
('cbSize', c_uint),
('dwTime', c_uint),
]
def get_idle_duration():
lastInputInfo = LASTINPUTINFO()
lastInputInfo.cbSize = sizeof(lastInputInfo)
windll.user32.GetLastInputInfo(byref(lastInputInfo))
millis = windll.kernel32.GetTickCount() - lastInputInfo.dwTime
return millis / 1000.0
printit()
time millis
返回的时间不正确。将其替换为 (win32api.GetTickCount() - win32api.GetLastInputInfo()) / 1000.0
可以解决这个问题。 - Sleepytime millis
返回的时间不正确。将其替换为 (win32api.GetTickCount() - win32api.GetLastInputInfo()) / 1000.0
可以解决这个问题。 - undefined实际上,您可以通过cytpes
库访问GetLastInputInfo
:
import ctypes
GetLastInputInfo = ctypes.windll.User32.GetLastInputInfo # callable function pointer
到目前为止,基本上有两种类型的答案。一种使用pywin32
(通过win32api
),另一种使用ctypes
。我能想到的唯一区别它们的执行时间,所以这里是一个timeit
测试的结果:
# idlefuncs.py
import ctypes
from ctypes import Structure, c_uint, sizeof, byref
import win32api
user32 = ctypes.WinDLL("user32", use_last_error=True)
kernel32 = ctypes.WinDLL("kernel32", use_last_error=True)
class LASTINPUTINFO(Structure):
_fields_ = [
('cbSize', c_uint),
('dwTime', c_uint),
]
def get_idle_duration():
lastInputInfo = LASTINPUTINFO()
lastInputInfo.cbSize = sizeof(lastInputInfo)
user32.GetLastInputInfo(byref(lastInputInfo))
millis = kernel32.GetTickCount() - lastInputInfo.dwTime
return millis / 1000.0
def getIdleTime():
return (win32api.GetTickCount() - win32api.GetLastInputInfo()) / 1000.0
In[1]: from idlefuncs import *
In[2]: %timeit get_idle_duration()
1.21 µs ± 12 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
In[4]: %timeit getIdleTime()
465 ns ± 7.69 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)