防止系统锁屏-python、C++实现
一、背景
作为一个开发,我的电脑经常是一个礼拜不关机,甚至时间更久,不知道在其他人看来这是不是一个常规操作。在日常工作中,我们的电脑也是一直处于非锁屏状态,出于对个人工作成果的安全性保护,我们公司给每个人的电脑上下发了一个组策略(属于强制下发,抗议无效),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 pag
x, y = pag.position() #返回鼠标的坐标
模拟鼠标、键盘操作,无非是鼠标点击、移动、键盘按下等,这些pyautogui
都已经提供,看名字就知道什么意思,这里我们先进行了鼠标点击,默认是左键,然后移动了鼠标位置,并且在最后按下了键盘上的esc键
pag.click()
pag.moveTo(x + 10, y + 10, 0.1)
pag.moveTo(x, y, 0.1)
writeLog('模拟一次鼠标移动\n')#
pag.press('esc')
writeLog('模拟点击esc\n')#
完整的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, y + 10, 0.1)
pag.moveTo(x, y, 0.1)
writeLog('模拟一次鼠标移动\n')#
pag.press('esc')
writeLog('模拟点击esc\n')#
else:
#更新旧坐标 最后一次移动鼠标时间
oldx = x
oldy = y
prev_time = now_time
#os.system('cls')#清楚屏幕
stay_seconds = (now_time - prev_time).seconds
writeLog('鼠标{}秒未移动\n'.format(stay_seconds))#打印坐标
posStr = "Position:" + str(x).rjust(4) + ',' + str(y).rjust(4)
writeLog(posStr + '\n')#打印坐标
time.sleep(2)
服务函数写完了,接下来是打包服务的过程,并启动服务
1. 打包服务成一个exe,pyinstaller -F aaa.py
2. 安装服务 python aaa.exe install
3. 启动服务 python aaa.exe start
4. 停止服务 python aaa.exe stop
5. 移除服务 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, y, 0, 0);
WriteToLog("模拟鼠标单击");
keybd_event('esc', 0, 0, 0);
keybd_event('a', 0, 0, 0);
WriteToLog("模拟点击esc");
}
}
else
{
//更新旧坐标 最后一次移动鼠标时间
oldx = x;
oldy = y;
prev_time = now_time;
}
接下来的操作就是我们需要把写好的服务安装并启动
1. sc create test binPath= 可执行文件的路径
2. net start test
3. net stop test
4. 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按键,但是上述操作都会不懂程度的带来一些影响。
例如:
- 如果用户正在看视频,没有进行键鼠操作,这个时候如果点击鼠标左键,可能会导致视频暂停,不是用户期望的操作
- 如果用户打开了一个弹框,例如顶层窗口是一个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, 0, RestoreWinState, NULL, 0, NULL); //创建线程01
CloseHandle(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, 0);
keybd_event(VK_CAPITAL, (BYTE)0, 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)", x, y);
WriteToLog(positionText);//打印坐标
Sleep(SLEEP_TIME);
}
子线程代码如下
void SimulationBehavior()
{
keybd_event(VK_CAPITAL, (BYTE)0, 0, 0);
keybd_event(VK_CAPITAL, (BYTE)0, KEYEVENTF_KEYUP, 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实现代码
![]() |
![]() |
很重要--转载声明
本站文章无特别说明,皆为原创,版权所有,转载时请用链接的方式,给出原文出处。同时写上原作者:朝十晚八 or Twowords
如要转载,请原文转载,如在转载时修改本文,请事先告知,谢绝在转载时通过修改本文达到有利于转载者的目的。
防止系统锁屏-python、C++实现的更多相关文章
- Android关闭系统锁屏
昨晚探索了一下Android系统内的目录,意外发现系统锁屏的数据库 使用adb shell进入系统根目录 adb shell su sqlite3 data/system/locksettings.d ...
- android屏蔽系统锁屏的办法
最近在开发一个第三方锁屏,使用中需要屏蔽系统锁屏,故代码如下: 在第三方锁屏的服务中onCreate()方法中(第三方锁屏服务启动时关闭一次系统锁屏服务即可) KeyguardManager mKey ...
- android 接受系统锁屏广播,及高版本发送广播
protected BroadcastReceiver messageReceiver = new BroadcastReceiver() { @Override public void onRece ...
- 007_苹果Mac系统锁屏不待机效果设置方法介绍
Mac如何设置锁屏不断网?Mac如何设置锁屏不待机?这是一个非常麻烦的设置,有时候一锁屏幕电脑就跟着待机了,这非常的麻烦,所以今天小编就用图文教程的方式教大家Mac如何设置锁屏不断网Mac如何设置锁屏 ...
- windows系统锁屏及修改密码项目开发经验记录
改造windows开机.锁屏登录流程需要使用微软停供的Credential Providers工程,编译出来是dll,安装在C:\windows\system32目录下,然后注册注册表(运行工程生成的 ...
- Android系统定制----删除系统锁屏功能【转】
本文转载自:http://blog.csdn.net/morixinguan/article/details/56675914 frameworks/base/packages/SettingsPro ...
- 【python】定时锁屏,保护身体
前言 最近越来越懒,一上班坐到电脑前就不愿意动,不喝水也不起来走动,一下班离开电脑就头晕眼花.想起前两年被肾结石支配的恐惧o(╥﹏╥)o,,,还是写个小工具强制自己喝水防止复发吧.VS Code启动 ...
- python Windows下的android设备截图工具
目录 界面版 命令行版 界面版 利用python的wx库写个ui界面,用来把android设备的截图输出到电脑屏幕,前提需要安装adb,涉及到的python库也要安装.代码如下: #!/usr/bin ...
- Python写一个Windows下的android设备截图工具
界面版 利用python的wx库写个ui界面,用来把android设备的截图输出到电脑屏幕,前提需要安装adb,涉及到的python库也要安装.代码如下: import wx,subprocess,o ...
随机推荐
- 测试驱动开发 TDD
一.详解TDD 1.1.TDD概念 :Test Drived Develop 测试驱动开发是敏捷开发中的一项核心实践和技术,也是一种方法论.TDD的原理是在开发功能代码之前,编写单元测试用例代码,测试 ...
- JVM学习记录-垃圾回收算法
简述 因为各个平台的虚拟机的垃圾收集器的实现各有不同,所以只介绍几个常见的垃圾收集算法. JVM中常见的垃圾收集算法有以下四种: 标记-清除算法(Mark-Sweep). 复制算法(Copying). ...
- 在Java中谈尾递归--尾递归和垃圾回收的比较(转载)
我不是故意在JAVA中谈尾递归的,因为在JAVA中谈尾递归真的是要绕好几个弯,只是我确实只有JAVA学得比较好,虽然确实C是在学校学过还考了90+,真学得没自学的JAVA好 不过也是因为要绕几个弯,所 ...
- HTML学习笔记5:修饰符和特殊标签
①修饰符: 作用:修饰显示的方式,并不改变网页的结构,需要修饰的内容写在修饰标签内 常用文字和段落修饰符: 文字斜体:<i></i> 或 <em> ...
- 深入理解.net - 3.类型Type
说到类型,.NET技术是基于通用类型系统(CTS,Common Type System)的,而CTS又是构建于公共语言架构(CLI,Common Language Infrastructure)之上, ...
- js算法初窥01(排序算法01-冒泡、选择、插入)
排序,我想大家一定经历过或者正在经历着.或许你不懂算法,对排序算法一无所知,但是你一定用过一些第三方库的api来一键排序,那么,在你享受便捷的同时,你是否想过它的底层是如何实现的?这样的算法实现方式是 ...
- 前端工程化(三)---Vue的开发模式
从0开始,构建前后端分离应用 导航 前端工程化(一)---工程基础目录搭建 前端工程化(二)---webpack配置 前端工程化(三)---Vue的开发模式 前端工程化(四)---helloWord ...
- spring中bean的scope属性理解
bean的scope属性有prototype,singleton,request, session几个属性 spring和struts2整合的时候,struts2的action要配置成scope=&q ...
- eclipse汉化链接
百度百科 https://jingyan.baidu.com/article/4b07be3cb1864e48b380f315.html 博客园:http://blog.csdn.net/sunny_ ...
- 在VirtualBox中安装BlackArch Linux
作者:荒原之梦 安装前的准备 下载系统映像:BlackArch Linux官网下载页面 在本文中我使用的是BlackArch Linux的Live ISO,这样可以减少安装时下载系统的时间.Black ...