C#实现远程锁屏

article/2025/7/20 18:10:53

前言

        这是一次提前下班没有锁屏进而引发的一次思考后的产物,思考的主要场景是当人离开电脑后,怎么能控制电脑锁屏,避免屏幕上的聊天记录被曝光。

        首先想到通过系统的电源计划设置闲置超时时间熄屏,这可能是最接近场景的解决方案,然后就考虑通过程序实现。刚开始认为这是在有限能力范围内最好的解决方案。但在尝试下面的方案二的时候又发现直接通过计划任务设置 12:00、18:00 两个一定会离开位置的自动锁屏时间也能解决问题。

        当时有一种执念,根据已知的信息来看,这肯定是能实现的,为什么现在没成功,必须要找到解决的方法,就这样一路摸索着最终调试通过。这个功能实现后还可以结合一些场景实现自动化,例如离开公司和回到家两个场景都可以触发锁屏。等等一些类似的场景在需要的时候自动触发锁屏。

正文

        这个想法在脑海里构思了几天,在今天(2024年5月10日)有时间来实践了,于是尝试在已有的会话状态程序中新增自动锁屏功能。

        简单介绍下这个会话状态程序,在多次沉迷代码不能自拔导致错过点餐最佳时间后。写的一个提醒程序,判断每天如果电脑被解锁时间超过30分钟,则通过企业微信机器人@是时候点餐了。后面又加入了如果明天是休息日提醒该填报工时了,又又加入如果电脑解锁时间超过30分钟并且今天是工作日检查今天是否有提交代码等待一些人在公司时的一些提醒。

        所以这个远程锁屏功能自然也就考虑继续往会话状态程序上加了。下面是锁屏功能的大致流程图,Windows 服务负责执行锁屏操作,Web 服务负责收集指令,伦理上什么都能做,只需要在Windows 服务中解析指令。

        接着就是通过搜索引擎实现想法的时候了,搜索关于锁屏很快就定位到一个清晰的方案一结果,这个看起来是如此的简单,果断复制下来加入 Program.cs 中调试,一击即中看起来核心的锁屏功能就实现了。那接下来就是把整个流程写完。流程的过程没有什么特别的,下面主要讲一讲实现锁屏的曲折过程。

方案一
// 引入 LockWorkStation 函数
[DllImport("user32.dll")]
private static extern bool LockWorkStation();        

        在 Windows 服务和 Web 服务代码写完调试通过后,于是开始发布准备联调。如果顺利文章到这里就可以结束,可能还需要感叹下以凑多些正文~~~

        好在凑正文的事情不用做了,因为方案一的代码发布后不生效,并且完全没有异常。在调试时好好的,一切正常,部署后就不行了。就现在这种情况搜索都不好找关键字。于是向 ChatGPT 求助「C# 锁屏操作,在调试的时候有效,但是发布后不行,这个应该怎么解决呢?」对方回复说是可能是权限问题、依赖问题、平台兼容性、错误处理和日志、环境差异。这些问题来大部分不存在的因为环境没有发生变化,都在同一台电脑上,唯有第一个权限问题是可能的,但是也并没有更清晰的方向,毕竟这个问法也是在为难 ChatGPT,然后又接着搜索 Windows 锁屏。

方案二
C# 代码
Process.Start("rundll32.exe", "user32.dll,LockWorkStation");CMD 代码
rundll32.exe user32.dll,LockWorkStation

        接着找到了方案二通过 CMD 执行锁屏,并且在 CMD 中执行使用代码也是能成功的,于是怀着试一试的态度开始改造 Windows 服务程序。代码也只有一行,其实也没什么好改的 ~~~

        很快改完发布,不出意外意外就没有出现,发布后的程序依然不能实现锁屏,由于怀疑是联调中间出了差错,都已经把逻辑直接放到了 Windows 服务启动项里面去了,只要服务能正常启动,锁屏逻辑就一定被执行。但是现在看起来屏幕并没有锁,到底是哪里出了问题,依然没有头绪。

        在继续搜索C#锁屏关键字时刷到一条信息,大概意思是说由于 Windows 服务属于后台任务,并不是当前登录用户通过操作启动的,Windows 出于安全考虑这类场景就不能与用户交互

        这就说得通了,到目前位置方案一和方案二的代码都没问题是确定的,问题就是我在调试时是通过 Visual Studio 启动的程序,此时属于用户操作启动的程序和 Windows 服务不是同一个会话的差别,此时这个场景下的程序还不是 Windows 服务所以能与用户交互,所以锁屏动作成功了。

        有了这个信息,我再回头和 ChatGPT 说,果然对方其实也是知道这个事情的,只是刚开始我没有向对方提起我这边是在 Windows 服务中使用的。现在场景清晰了,并给我5个建议的方向使用计划任务、使用WCF或命名管道通信、通过COM激活、利用任务调度器Interactive Option,使用Messager API 或 SendSignal utility,果然很专业的样子,但是我一个都不想选。

        我想到了另外两个方向,通过触发快捷键和单独写一个 WinFrom 程序。这两个方法看起来都要比给出的5个方向简单,因为这两个方向有熟悉的味道。

        很快结论就出来了,这段是关于快捷键的,SendKeys 很可能也是出于安全考虑,不能触发 Win 键,Ctrl、Shift、Delete 都能触发唯独不能触发 Win 键 ~~~ 按理说肯定有办法的,只是现在还不知道怎么做。好在还有一个备选方案,马不停蹄继续。

        继续用方案二的 C# 代码执行锁屏 WinFrom 操作,代码也只有一段,可惜就是不成功,原因和最开始发现的一样,作为 Windows 服务无论做什么操作都是在相同 Session 中状态下执行的,Windows 服务不能与用户交互,即使 Windows 服务启动一个有界面的 WinFrom 程序也不能与用户交互(其实界面并没有出现)。就算一直套娃下去依然不能。

        然后就回去把这个情况给 ChatGPT 反馈了,对方得知这个情况后并没有嘲笑或指责没有听话照做,反而是在现有场景上给出了新的建议,大概是:如果要在 Windows 服务中通过 WinFrom 来执行锁屏操作也不是不可能,前提是这个 WinFrom 需要提前启动,可以是用户启动甚至是开机自动启动,只要不是 Windows 服务去启动的都可以。接着再由 Windows 服务与 WinFrom 通讯告诉 WinFrom 去执行锁屏这样就没问题。

        方案是有了,并且这应该是能成功的,但是现在电脑上已经有一个 Windows 服务了,如果为了这个功能再跑一个程序,感觉上不是很爽,不希望把程序的复杂度摊开来降低使用体验。只能重新审视 ChatGPT 最开始提出的5个方向了。刚开始看的时候都没有仔细思考这些关键字,现在回头看,第一个有熟悉的味道。        

方案二调整
/// <summary>
/// 通过 CMD 执行命令
/// </summary>
/// <param name="applocaltion"></param>
/// <param name="argument"></param>
private static void Exec(string applocaltion, string argument)
{using (var process = new Process()){process.StartInfo.Arguments = argument;process.StartInfo.FileName = applocaltion;process.StartInfo.UseShellExecute = false;process.StartInfo.RedirectStandardInput = true;process.StartInfo.RedirectStandardOutput = true;process.StartInfo.RedirectStandardError = true;process.StartInfo.CreateNoWindow = true;process.Start();process.StandardInput.AutoFlush = true;process.StandardInput.WriteLine("exit");//获取cmd窗口的输出信息  //string output = process.StandardOutput.ReadToEnd();process.WaitForExit();process.Close();}
}// 调用方法
Exec("schtasks", $"/create /tn {_name} /tr \"rundll32.exe user32.dll,LockWorkStation\" /sc once /st {DateTime.Now.AddMinutes(1):HH:mm} /f");

       计划任务是一个系统服务,Windows 服务创建一个计划任务去执行锁屏操作这样就跳出了 Windows 服务不能与用户交互的限制。

        直接通过方案二的代码执行 schtasks 时会抛出异常「System.ComponentModel.Win32Exception:“系统找不到指定的文件。”」调整方案二的代码后就能正常跑起来。

        一晃一个多小时过去了,现在的情况比最开始的方案一有进展,但并不多,好消息是计划任务创建成功了,并且调试的时候也没问题。坏消息是发布后计划任务超时了也没有执行锁屏。

        仔细思考怀疑通过 CMD 来创建的计划任务很有可能还没有跳出 Session 的场景(其实不是)。于是问 ChatGPT 还有哪些方法可以创建,于是就推荐了 Microsoft.Win32.TaskScheduler NuGet 第三方组件来创建计划任务,于是抱着有路就要试一试的态度再次调整逻辑开始了方案三。

方案三
引入 NuGet 包:Microsoft.Win32.TaskScheduler;using (var ts = new TaskService())
{// 创建新任务var td = ts.NewTask();td.RegistrationInfo.Description = "定时锁屏";// 设置触发器,或其他触发器,如WeeklyTrigger、MonthlyTrigger等td.Triggers.Add(new TimeTrigger { StartBoundary = DateTime.Now.AddMinutes(1) });td.Actions.Add(new ExecAction("rundll32.exe", "user32.dll,LockWorkStation", null)); // 设置操作// 注册任务,并且需要指定登录的系统账号密码才能在成功ts.RootFolder.RegisterTaskDefinition(_name, td, TaskCreation.CreateOrUpdate, "administrator", "123456", TaskLogonType.InteractiveTokenOrPassword);
}

        经过漫长的几个小时调试,终于在调试方案三的过程中突然锁屏了。一开始的情况和方案二一样,也是调试的时候没问题,发布就没效果。在不断向 ChatGPT 逼问下,对方说可能是权限问题,说可以指定账号密码试试。在加上账号密码过程中调试了N多次,每调试一次都需要等待至少一分钟。

        这个过程中才发现原来计划任务指定的执行时间并不是准时的分钟,而且每分钟检查一次是否执行,而前面在不知道这个前提的情况下,一直守着系统秒跳到00,发现没执行又是一阵排查调整,可想而知绝大部分的调整都是没有效果的。直到加上了系统账号密码,紧接着分析为什么成功了,通过 Ctrl + Z 回滚大法最终确认是因为加上了下面加租的参数。

ts.RootFolder.RegisterTaskDefinition(_name, td, TaskCreation.CreateOrUpdate, "administrator", "123456", TaskLogonType.InteractiveTokenOrPassword);

        也就是说因为前面提到 Windows 服务的特殊情况,必须指定一个已经登录了用户并且输入密码才能在创建的任务中触发操作。

        一开始也是不愿意加账号密码的,考虑到如果这个 Windows 服务要是装在多台电脑上,还需要修改对应的账号密码,如果改成配置文件一是感觉不安全,二是现在程序还没有配置文件 ~~~,但是最终没有抗住加上就成功了。现在回头看如果在方案二中加上账号密码也能成功。

        最后再献上通过 CMD 创建、执行、删除计划任务的代码

# 创建任务:在指定时间执行一次锁屏,如果任务存在则覆盖
schtasks /create /tn LockScreen /tr "rundll32.exe user32.dll,LockWorkStation" /sc once /st 09:24 /f# 手动执行任务
schtasks /run /tn LockScreen# 强制删除任务
schtasks /delete /tn LockScreen /f

参考资料:

一、使用C#创建计划任务(How to create a Task Scheduler use C# )_使用c#实现计划任务-CSDN博客

二、Task Scheduler Managed Wrapper


http://www.hkcw.cn/article/xdhlKvkZjr.shtml

相关文章

重读《人件》Peopleware -(15)Ⅱ 办公环境 Ⅷ 撑伞之步:构建理想办公环境(上)

在本章中&#xff0c;我们将探讨理想办公环境的特点&#xff0c;并尝试回答以下问题&#xff1a; 什么样的空间能最好地让员工感到舒适、快乐和高效&#xff1f; 什么样的工作空间能让员工对自己的工作感到最满意&#xff1f; 如果你在一个典型的嘈杂且单调的企业环境中工作…

兰博基尼车主赖停车费被代驾举报酒驾 5元引发的酒驾案

近日,浙江宁波一名兰博基尼车主酒后请代驾将车开到小区,随后自己开车进车库。因不愿支付代驾小哥垫付的5元停车费,被对方举报酒驾。经检测,该车主血液中的酒精含量达59mg/100ml,达到酒驾标准,其驾驶证被扣12分,暂扣6个月,并被处以2000元以下罚款。事发当晚11时30分许,…

乌总统称亲自筹划蛛网行动一年半 精心策划载入史册

乌克兰在与俄罗斯举行第二轮谈判前夕,发动了“蛛网”行动,袭击了俄罗斯多地。据报道,此次行动中的无人机是通过货柜车偷运进入俄方领土的。乌克兰总统泽连斯基表示,准备工作超过一年半,并且经过精心策划。他赞扬此次行动堪称精彩,并形容乌军此次行动“无疑将载入史册”。…

“13**0000000”手机号卖了61.2万 司法拍卖市场火热

端午节期间,司法拍卖市场异常活跃。6月1日,一个尾号为“0000000”的手机号码使用权以25万元起拍,吸引了13人报名竞拍。经过激烈竞争,截至6月2日上午拍卖结束时,该号码最终以61.2万元成交。根据竞买公告,这个手机号码截至2025年4月23日没有欠费,余额约为9.14元。套餐为4G…

西班牙伊维萨岛限制旅游用车数量 应对过度旅游挑战

西班牙伊维萨岛是地中海热门旅游目的地,每逢旅游旺季游客蜂拥而至,带来一系列问题。为应对“过度旅游”,该岛在6月1日至9月30日期间对旅游用车数量做出限制。当地政府规定,在这四个月期间,岛上非居民每天可用汽车数量上限为20168辆。其中1.6万辆分配给岛上的租赁汽车,其余…

俄通报乌克兰无人机袭击损失 乌方称摧毁数十架战机

乌克兰官员周日表示,乌克兰军队对俄罗斯境内深处的多个军用机场发动了大规模无人机袭击。这些机场是用于进行空袭的战略轰炸机基地,这次行动被认为是自俄乌冲突爆发以来乌克兰军队最大胆的军事行动之一。乌克兰主要安全情报机构乌克兰安全局官员透露,此次被称为“蛛网”的袭…

基于ssm+mysql的大创项目申报管理系统(含LW+PPT+源码+系统演示视频+安装说明)

系统功能 管理员功能&#xff1a;用户信息管理、工作人员管理、项目模板管理、项目申报管理、往届项目管理、我的项目申报管理&#xff1b;工作人员功能&#xff1a;项目申报内容管理、项目申报模板管理、往届项目信息管理、我的项目申报管理、项目申报内容审核、项目内容批量…

美佛罗里达州官宣金银为法定货币 增强金融自由

5月27日,美国佛罗里达州州长德桑蒂斯签署了一项法案,正式将符合特定纯度标准的黄金和白银硬币认定为该州的法定货币。他表示,此举旨在增强佛罗里达州居民的金融自由,并抵御美元贬值带来的风险。高盛集团最新研报指出,在对冲美元崩盘风险方面,黄金比比特币更合适。犹他州是…

论文略读:Uncertainty-Aware Graph Structure Learning

WWW 2025 1 intro 传统GNN忽视了图结构自身存在的缺陷: 图结构常常会出现错误边和缺失边等数据问题&#xff0c;从而限制模型的效果 —>为了解决上述问题&#xff0c;产生了图结构学习算法&#xff08;GSL&#xff09; 目的在于优化结点连接和边权重来生成新的邻接矩阵主流…

6.运算放大器—增益带宽积(六)

增益带宽积&#xff08;GBW&#xff09;是运算放大器&#xff08;Op-Amp&#xff09;和许多放大电路的核心参数&#xff0c;它描述了放大器在增益和带宽之间的权衡关系。 定义为在某频率下测量的运放开环增益与测量频率的乘积&#xff0c;其单位为Hz。 这个参数被用来评估运放的…

K8s包管理工具-helm:helm安装

1 Helm的简介 每个成功的软件平台都有一个优秀的打包系统&#xff0c;比如 Debian、Ubuntu 的 apt&#xff0c;Redhat、Centos 的 yum。而 Helm 则是 Kubernetes 上的包管理器。 1.1 为什么k8s需要Helm&#xff1f; Kubernetes 能够很好地组织和编排容器&#xff0c;但它缺…

OpenAI 宕机 | 如何让 k8s 集群更稳定

注:本文为 2024 年 12 月 “ OpenAI 宕机分析” 相关文章合辑。 未整理去重。 ChatGPT 的故障,官方这样解释… 明说 YYM 2024 年 12 月 14 日 18:50 广东 2024 12 11 (PST) OpenAI 经历了一次服务故障,OpenAI 给出了详细的解释和预防方案。下面是我阅读的分析和部分解读。…

自定义资源支持:K8s Device Plugin 从原理到实现

本文主要分析 k8s 中的 device-plugin 机制工作原理&#xff0c;并通过实现一个简单的 device-plugin 来加深理解。 1. 背景 默认情况下&#xff0c;k8s 中的 Pod 只能申请 CPU 和 Memory 这两种资源&#xff0c;就像下面这样&#xff1a; resources:requests:memory: "…

在K8S上部署OceanBase的最佳实践

在K8S上部署OceanBase的最佳实践 目录 1. 背景与选型 1.1 为什么选择OB1.2 为什么选择ob-operator实现OB on K8S 2. 部署实操 2.1 环境准备2.2 安装 ob-operator2.3 配置 OB 集群2.4 配置 OBProxy 集群2.5 Headless Service 和 CoreDNS 配置2.6 监控与运维 2.6.1 Promethues部…

Centos 安装 Kubernets(k8s)

Centos安装部署Kubernetes (k8s) cat /etc/os-release #查看系统版本 uname -r #查看系统内核 1.设置主机名 准备三台服务器&#xff0c;至少2核2G hostnamectl set-hostname k8s-master #在第一台机器上执行hostnamectl set-hostname k8s-node01 #在第二台机器上执行hostna…

K8s - openeuler2203SP1安装 K8s + flannel

环境说明 [rootmaster-1 ~]# uname -a Linux master-1 5.10.0-136.12.0.86.oe2203sp1.x86_64 #1 SMP Tue Dec 27 17:50:15 CST 2022 x86_64 x86_64 x86_64 GNU/Linux安装过程 1、安装 containerd 下载 tar 包 # 确保没有使用官方仓库的containerd [rootlocalhost ~]# yum rem…

K8S从0完整搭建

介绍 以下搭建的环境使用的是VMware虚拟机。这里大家可以自行选择。K8S每个版本可能都会有差异&#xff0c;请保证相关组件的兼容性。 准备工具 部署版本介绍 名称 版本 描述 centos 7.9 docker 20.10.8 k8s v1.20.10 calico v3.20.0 K8S节点规划 3个m…

【Kubernetes】k8s的helm扩展之监控管理、日志管理、部署efk【elk的升级版】详细说明

部署prometheus【mon节点】 镜像查看【需要先配置好helm源,这里是配置的ali源】【集群必须通外网才能部署啊】helm search repo prometheus-operator 安装prometheushelm install mon ali/prometheus-operator【后面就是上面查询到的helm信息】 下载完毕以后呢就会有一个helm…

最全Linux centos9环境基于k8s(k3s)搭建HomeAssistant,并接入米家官方XiaoMiHome插件

背景 环境 1、linux centos 9&#xff08;该环境的ip可以被你的其他设备访问到&#xff0c;例如你可以用windows访问到家里的服务器&#xff09; 2、k3s集群已完成部署&#xff0c;参考:国内k3s环境搭建-CSDN博客 3、HA部署方式采用容器化部署 概念 1、k3s&#xff1a;k8…

Git 使用全指南

Git 使用全指南 第一部分&#xff1a;核心概念 什么是 Git&#xff1f; 一个分布式版本控制系统 (DVCS)。目标&#xff1a; 跟踪文件变化、协作开发、回溯历史、管理不同开发线&#xff08;分支&#xff09;。核心思想&#xff1a; 每个开发者都有完整的仓库副本&#xff08;包…