一、背景
作为一个开发,我的电脑经常是一个礼拜不关机,甚至时间更久,不知道在其他人看来这是不是一个常规 *** 作。在日常工作中,我们的电脑也是一直处于非锁屏状态,出于对个人工作成果的安全性保护,我们公司给每个人的电脑上下发了一个组策略(属于强制下发,抗议无效), 5min不对电脑进行 *** 作,电脑就锁屏 ,这可真是令人 *** 蛋,出去上个厕所的功夫电脑就锁屏啦、和别人讨论问题的功夫电脑又锁屏了,作为一个开发,这真不能忍。
最近一直在学习 python ,刚好接触到了 python 写 windows 服务相关的一些东西,嘿嘿,5分钟不 *** 作电脑锁屏是吧,那么我们在无任何 *** 作下2分钟给他模拟一次键盘或者鼠标 *** 作可好。
二、模拟鼠标、键盘事件
要写一个 windows 服务也是比较简单的,只需要继承自win32serviceutil.ServiceFramework这个类,然后实现相关方法即可,主要的方法是SvcDoRun,服务启动后,该方法处于激活状态,该方法结束服务退出
具体的实现方式可参考 Python-定时爬取指定城市天气(二)-邮件提醒 文章中的第三小节,优化定时任务。
1、 python 实现
这里我只贴出关键代码,服务的整体框架不在细说,不会的同学请看这里 Python-定时爬取指定城市天气(二)-邮件提醒
a、 python 服务
首先判断鼠标2分钟内是否有 *** 作,我们需要能获取到当前鼠标位置的函数, pyautogui 是一个 python 的自动化库,满足我们的需求,该库提供了丰富的鼠标、键盘 *** 作,使用该库,首先就得使用pip进行安装
pip install pyautogui
使用方式如下,x和y即是当前鼠标相对于屏幕左上角(0,0)的坐标
import pyautogui as pagx,y = pag.position() #返回鼠标的坐标
模拟鼠标、键盘 *** 作,无非是鼠标点击、移动、键盘按下等,这些 pyautogui 都已经提供,看名字就知道什么意思,这里我们先进行了鼠标点击,默认是左键,然后移动了鼠标位置,并且在最后按下了键盘上的esc键
pag.click()pag.moveto(x + 10,y + 10,0.1)pag.moveto(x,y,0.1)writeLog('模拟一次鼠标移动')#pag.press('esc')writeLog('模拟点击esc')#
完整的SvcDoRUn函数如下
def SvcDoRun(self): #what to do# prev_time = datetime.datetime.Now() oldx = 0 oldy = 0 while self.run: x,y = pag.position() #返回鼠标的坐标 Now_time = datetime.datetime.Now() if x == oldx and y == oldy: stay_seconds = (Now_time - prev_time).seconds if stay_seconds >= 60: prev_time = Now_time pag.click() pag.moveto(x + 10,0.1) pag.moveto(x,0.1) writeLog('模拟一次鼠标移动')# pag.press('esc') writeLog('模拟点击esc')# else: #更新旧坐标 最后一次移动鼠标时间 oldx = x oldy = y prev_time = Now_time #os.system('cls')#清楚屏幕 stay_seconds = (Now_time - prev_time).seconds writeLog('鼠标{}秒未移动'.format(stay_seconds))#打印坐标 posstr = "position:" + str(x).rjust(4) + ',' + str(y).rjust(4) writeLog(posstr + '')#打印坐标 time.sleep(2)
服务函数写完了,接下来是打包服务的过程,并启动服务
1. 打包服务成一个exe,pyinstaller -F aaa.py2. 安装服务 python aaa.exe install3. 启动服务 python aaa.exe start 4. 停止服务 python aaa.exe stop5. 移除服务 python aaa.exe remove
执行上述流程的1、2和3,服务就已经被成功启动,但不幸的是发现 pag.position() 返回的坐标一直是0,各种测试都不对,开始怀疑是服务里可能找不到 pyautogui 资源导致失败,后来在网上找了另一种或许鼠标位置的函数
def get_mouse_point(): po = POINT() windll.user32.GetCursorPos(byref(po)) return int(po.x),int(po.y)
经过测试,该函数单独运行时没有问题,放在服务里拿到的坐标还是(0,0),写服务的路子算是泡汤啦
为了更好的查找服务的运行状态,我们这里把服务的运行时状态卸载了一个文件里,写日志代码如下
#写日志def writeLog(msg): try: f = open('./prevent_lock_screen.log','a',enCoding = 'utf-8') f.write(datetime.datetime.Now().strftime('%Y-%m-%d %H:%M:%s') + ':' + msg) f.close() except BaseException: pass
b、 python 函数
python 服务的方式暂时算是中断了,但是我们还是不能放弃啊,经过尝试, 把运行在服务里的代码拿出来放在正常 python 文件里执行还是好使的 。不明所以啊, ++哪位大神如果知道服务里的代码为什么运行失败,还请评论区支出,不胜感激。。。++
为了防止电脑自动锁屏,要一直运行一个 dos 窗口看起来确实挺扯的,初学 python 可能好多东西还是不懂,因此为了让这个需求更优雅一些,我拿起了 C++ ,我们还是先来写一个服务吧
2、 C++ 实现
为了实现这个需求,我也真是拼了
a、 C++ 服务
不得不说, C++ 写服务还是挺费劲的,在网上扒了一个服务的模子,我便开始写了,其实最主要的还是要实现服务中的死循环函数,代码逻辑和上述 python 的思路一起,区别就是我们需要使用 C++ 的语法实现一遍而已。
POINT p; GetCursorPos(&p);//获取鼠标坐标 int x = p.x,y = p.y;//返回鼠标的坐标 time_t Now_time = time(NulL); if (x == oldx && y == oldy) { int stay_seconds = int(Now_time - prev_time); if (stay_seconds >= 6) { prev_time = Now_time; SetCursorPos(x + 10,y + 10); SetCursorPos(x,y); WritetoLog("模拟一次鼠标移动"); mouse_event(MOUSEEVENTF_leftDOWN | MOUSEEVENTF_leftUP,x,0); WritetoLog("模拟鼠标单击"); keybd_event('esc',0); keybd_event('a',0); WritetoLog("模拟点击esc"); } } else { //更新旧坐标 最后一次移动鼠标时间 oldx = x; oldy = y; prev_time = Now_time; }
接下来的 *** 作就是我们需要把写好的服务安装并启动
1. sc create test binPath= 可执行文件的路径2. net start test3. net stop test4. net delete test
执行上述步骤1和2即可启动服务
经过测试,太不幸了, GetCursorPos(&p) 返回的坐标也为(0,0),这下真是郁闷了,服务这条路难道真的走不通了吗?看到的大神有解决思路的还请在评论区支出,不胜感激。。。
b、 C++ 可执行程序
照搬照抄上述 python 服务转可执行程序的逻辑,我们把 C++ 服务里的代码拿出来,放到 C++ 可执行程序中,我们也可以实现一个 C++ 可执行程序
进过测试,以上 python 程序和 C++ 程序都还有一些问题,在一些特定的窗口上模拟鼠标、键盘 *** 作不好使,比如 notepad ++ 、windows任务管理器等,系统在5分钟后还是锁屏,思前想后,觉着这个可能和程序权限有关系, 随即把 C++ 工程的属性进行了调整,生成的exe需要带有管理员权限,在次进行测试,结果是完美的 ,我们终于可以防止系统自动锁屏了,执行上述python的程序这里就不做权限升级研究了,有兴趣的同学自行研究
c++ 程序我们可以通过设置来吧程序设置成后台运行的,没有任何界面,这样显得更优雅一些,首先我们创建的是一个dos程序,设置设置两个地方即可
连接器->系统:子系统设置成窗口 (/SUBSYstem:windows) 连接器->高级:入口点设置成mainCRTStartup三、优化
最开始的模拟用户 *** 作,我们使用的是点击鼠标左键、移动鼠标、和模拟点击esc按键,但是上述 *** 作都会不懂程度的带来一些影响。
例如:
如果用户正在看视频,没有进行键鼠 *** 作,这个时候如果点击鼠标左键,可能会导致视频暂停,不是用户期望的 *** 作 如果用户打开了一个d框,例如顶层窗口是一个esc快捷键可以关闭的程序,这个时候如果用户2分钟没有 *** 作电脑,那么模拟的esc按键将会把用户的原始状态打乱模拟 *** 作优化过程
1、win+d
切换到桌面,随即在开切换回来,这个 *** 作相对来说比较靠谱,但是如果有一个窗口上有模态窗口存在,也会对打乱原始的窗口顺序
2、win键
点击 windows 键,随即在点击一次,恢复到点击之前的状态,这个 *** 作相对第一种还是比较友好的
3、切换大小写
点击CapsLk按键,进行大小写切换,由于这个时候用户没有 *** 作电脑,因此切换大小写不会对用户 *** 作进行干扰,而且动静更小、更优雅
上述3中模拟 *** 作行为基本思路都是一样的,只是模拟的方式所有不同,下边我们就以第三种方式讲解实现过程
点击CapsLk的 *** 作分两部分,第一次主要是为了模拟用户点击,第二次是为了恢复第一次 *** 作留下的痕迹,为了让程序更优雅的运行,我们这里需要启动子线程来恢复主线程留下的痕迹
main函数代码如下
hMutex = CreateMutex(NulL,FALSE,(LPCWSTR)"PreventLockScreenApp");WaitForSingleObject(hMutex,INFINITE);HANDLE hThread = CreateThread(NulL,RestoreWinState,NulL,NulL); //创建线程01CloseHandle(hThread); //关闭句柄remove(LOGfile);time_t prev_time = time(NulL);//int oldx = 0;int oldy = 0;char positionText[100] = { 0 };sprintf(positionText,"防锁屏进程已启动,程序将在无鼠标移动情况下每隔%d秒模拟一次键盘 *** 作",Job_TIME);WritetoLog(positionText);while (1){ POINT p; GetCursorPos(&p);//获取鼠标坐标 int x = p.x,y = p.y;//返回鼠标的坐标 time_t Now_time = time(NulL); if (x == oldx && y == oldy) { int stay_seconds = int(Now_time - prev_time); if (stay_seconds >= Job_TIME) { prev_time = Now_time; keybd_event(VK_CAPITAL,(BYTE)0,0); keybd_event(VK_CAPITAL,KEYEVENTF_KEYUP,0); WritetoLog("模拟点击CapsLk,切换大小写"); //释放锁 让子线程去恢复win键状态 ReleaseMutex(hMutex); Sleep(Restore_TIME / 2); WaitForSingleObject(hMutex,INFINITE); } } else { //更新旧坐标 最后一次移动鼠标时间 oldx = x; oldy = y; prev_time = Now_time; } int stay_seconds = int(Now_time - prev_time); char mousemoved[100] = { 0 }; sprintf(mousemoved,"鼠标%d秒未移动",stay_seconds); WritetoLog(mousemoved);//打印坐标 char positionText[100] = { 0 }; sprintf(positionText,"当前鼠标位置(%d,%d)",y); WritetoLog(positionText);//打印坐标 Sleep(SLEEP_TIME);}
子线程代码如下
voID SimulationBehavior(){ keybd_event(VK_CAPITAL,0);}DWORD WINAPI RestoreWinState(LPVOID lvParamter){ while (true) { WaitForSingleObject(hMutex,INFINITE); Sleep(Restore_TIME); SimulationBehavior(); ReleaseMutex(hMutex); } return 0;}
主子线程使用一个全局的信号量来进行同步
四、demo下载
需要 C++ 和 python 代码的同学到 csdn 下载: C++实现的防锁屏后台进程-内含python实现代码
进群:548377875 即可获取数十套pdf!
总结以上是内存溢出为你收集整理的防止系统锁屏-python、C++实现!全部内容,希望文章能够帮你解决防止系统锁屏-python、C++实现!所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)