C#實現遠程鎖屏

前言

????????這是一次提前下班沒有鎖屏進而引發的一次思考后的產物,思考的主要場景是當人離開電腦后,怎么能控制電腦鎖屏,避免屏幕上的聊天記錄被曝光。

? ? ? ? 首先想到通過系統的電源計劃設置閑置超時時間熄屏,這可能是最接近場景的解決方案,然后就考慮通過程序實現。剛開始認為這是在有限能力范圍內最好的解決方案。但在嘗試下面的方案二的時候又發現直接通過計劃任務設置 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.pswp.cn/diannao/85332.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/85332.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/85332.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

[Protobuf]常見數據類型以及使用注意事項

[Protobuf]常見數據類型以及使用注意事項 水墨不寫bug 文章目錄 一、基本數據類型1、字段2、字段的修飾規則 二、自定義數據類型1、message類型2、enum類型3、Any類型4、oneof類型5、map類型 三、小工具1.hexdump2.decode 四、注意事項 一、基本數據類型 protobuf 支持多種基礎…

JS分支和循環

程序的執行順序 在程序開發中&#xff0c;程序有三種不同的執行順序 1.順序執行 2.分支執行 3.循環執行 程序的代碼塊 <script>//一個代碼塊{var num11var num22var num3num1num2}//一個休想var info{name:"chen",age:18} 1.if分支語句&#xff08;單分支語句&…

Android 開發 Kotlin 全局大喇叭與廣播機制

在 Android 開發中&#xff0c;廣播機制就像一個神通廣大的 “消息快遞員”&#xff0c;承擔著在不同組件間傳遞信息的重任。Kotlin 語言的簡潔優雅更使其在廣播機制的應用中大放異彩。今天&#xff0c;就讓我們一同深入探索 Android 開發中 Kotlin 全局大喇叭與廣播機制的奧秘…

rabbitmq AI復習

RabbitMq rabbitmq &#x1f9d1;?&#x1f4bb; User 幫我復習rabbitmq相關知識&#xff0c;我是一個經驗豐富的程序員 &#x1f916; Assistant 好的&#xff01;很高興能通過這種方式幫你復習或學習 RabbitMQ 的知識。按照你說的流程&#xff0c;我們從完全零基礎開始&…

計算機視覺---YOLOv5

YOLOv5理論講解 一、YOLOv5 整體架構解析 YOLOv5 延續了 YOLO 系列的 單階段目標檢測框架&#xff0c;包含 主干網絡&#xff08;Backbone&#xff09;、頸部網絡&#xff08;Neck&#xff09; 和 檢測頭&#xff08;Head&#xff09;&#xff0c;但在結構設計上更注重 輕量化…

C++多重繼承詳解與實戰解析

#include <iostream> using namespace std; //基類&#xff0c;父類 class ClassA { public:void displayA() {std::cout << "Displaying ClassA" << std::endl;}void testFunc(){std::cout << "testFunc ClassA" << std::e…

單細胞注釋前沿:CASSIA——無參考、可解釋、自動化細胞注釋的大語言模型

細胞類型注釋是單細胞RNA-seq分析的重要步驟&#xff0c;目前有許多注釋方法。大多數注釋方法都需要計算和特定領域專業知識的結合&#xff0c;而且經常產生不一致的結果&#xff0c;難以解釋。大語言模型有可能在減少人工輸入和提高準確性的同時擴大可訪問性&#xff0c;但現有…

STM32Cubemx-H7-17-麥克納姆輪驅動

前言 --末尾右總體的.c和.h 本篇文章把麥克納姆輪的代碼封裝到.c和.h&#xff0c;使用者只需要根據輪子正轉的方向&#xff0c;在.h處修改定義方向引腳&#xff0c;把輪子都統一正向后&#xff0c;后面的輪子驅動就可以正常了&#xff0c;然后直接調用函數驅動即可。 設置滿…

文檔核心結構優化(程序C++...)

文檔核心結構優化 一、文檔核心結構優化二、C關鍵特性詳解框架2.1 從C到C的范式遷移 三、深度代碼解析模板3.1 現代C特性分層解析 四、C vs C 關鍵差異矩陣五、交互式文檔設計策略5.1 三維學習路徑5.2 代碼缺陷互動區 六、現代C特性演進圖七、性能優化可視化呈現&#xff08;深…

PyTorch ——torchvision數據集使用

如果下載的很慢&#xff0c;可以試試下面這個

純前端實現圖片偽3D視差效果

作者&#xff1a;vivo 互聯網前端團隊- Su Ning 本文通過depth-anything獲取圖片的深度圖&#xff0c;同時基于pixi.js&#xff0c;通過著色器編程&#xff0c;實現了通過深度圖驅動的偽3D效果。該方案支持鼠標/手勢與手機陀螺儀雙模式交互&#xff0c;在保證性能的同時&#x…

英語寫作中“專注于”focus on、concentrate的用法

Focus on在論文寫作中常用&#xff0c;指出研究點&#xff0c;例如&#xff1a; There are three approaches to achieving ID authentication. Our study will focus on ……&#xff08;有三種途徑實現身份認證&#xff0c;我們的研究專注于……&#xff09; concentrate &…

go環境配置

下載對應版本的 go 版本 https://go.dev/dl/ 配置 vim ~/.zshrc export GOROOT/usr/local/go export PATH$PATH:$GOROOT/binsource ~/.zshrc >>>>>> go versiongoland 配置&#xff1a; &#x1f50d; 一、什么是GOPATH&#xff1f; GOPATH 是舊的項目結…

AI Agent智能體:底層邏輯、原理與大模型關系深度解析·優雅草卓伊凡

AI Agent智能體&#xff1a;底層邏輯、原理與大模型關系深度解析優雅草卓伊凡 一、AI Agent的底層架構與核心原理 1.1 AI Agent的基本構成要素 AI Agent&#xff08;人工智能代理&#xff09;是一種能夠感知環境、自主決策并執行行動的智能系統。其核心架構包含以下關鍵組件…

【手搓一個原生全局loading組件解決頁面閃爍問題】

頁面閃爍效果1 頁面閃爍效果2 封裝一個全局loading組件 class GlobalLoading extends HTMLElement {constructor() {super();this.attachShadow({ mode: open });}connectedCallback() {this.render();this.init();}render() {this.shadowRoot.innerHTML <style>.load…

unix/linux source 命令,其高級使用

就像在物理學中,掌握了基本定律后,我們可以開始研究更復雜的系統和現象,source 的高級用法也是建立在對其基本行為深刻理解之上的。 讓我們一起探索 source 的高級應用領域: 1. 條件化加載 (Conditional Sourcing) 根據某些條件來決定是否 source 一個文件,或者 source…

DexGarmentLab 論文翻譯

單個 專家 演示 裝扮 15 任務 場景 2500+ 服裝 手套 棒球帽 褲子 圍巾 碗 帽子 上衣 外套 服裝-手部交互 捕捉 搖籃 夾緊 平滑 任務 ...... 投擲 懸掛 折疊 ... 多樣化位置 ... 多樣化 變形 ... 多樣化服裝形狀 類別級 一般化 類別級(有或沒有變形) 服裝具有相同結構 變形 生…

WPF-Prism學習筆記之 “導航功能和依賴注入“

新建空白模板(Prism) 新建好后會有自動創建ViewModels和Views 在"MainWindow.xaml"文件里面標題去綁定了一個屬性"Title"&#xff0c;而"MainWindowViewModel.cs"里面繼承一個非常重要的"BindbleBase"(prism框架里面非常重要的)。所以…

《C++初階之入門基礎》【C++的前世今生】

【C的前世今生】目錄 前言&#xff1a;---------------起源---------------一、歷史背景二、橫空出世---------------發展---------------三、標準立世C98&#xff1a;首個國際標準版本C03&#xff1a;小修訂版本 四、現代進化C11&#xff1a;現代C的開端C14&#xff1a;對C11的…

YOLOv5-入門篇筆記

1.創建環境 conda create -n yolvo5 python3.8 去pytorch.org下載1.8.2的版本。 pip --default-timeout1688 install torch1.8.2 torchvision0.9.2 torchaudio0.8.2 --extra-index-url https://download.pytorch.org/whl/lts/1.8/cu111 github上下載yolov5的zip pip --def…