讲师中心 微信公众号
AI工具推荐 视频效率加速

C++如何实现跨平台获取系统锁屏状态?(Windows LockWorkStation监听)

轻宇大大_5131

轻宇大大_5131

发布时间:2026-02-24 16:15:10

|

920人浏览过

|

来源于php中文网

原创

应使用系统提供的会话状态通知机制:Windows 用 WTSRegisterSessionNotification 监听 WM_WTSSESSION_CHANGE 消息,macOS 用 CGSessionCopyCurrentDictionary 轮询 kCGSessionIsLockedKey 并辅以 IOKit 监听,Linux 通过 systemd-logind D-Bus 接口监听 LockSession/UnlockSession 信号。

c++如何实现跨平台获取系统锁屏状态?(windows lockworkstation监听)

Windows 上怎么检测用户是否锁屏?用 WTSRegisterSessionNotification 而不是轮询 GetAsyncKeyState

直接轮询键盘或鼠标状态来“猜”锁屏是错的——锁屏后系统仍可能有后台输入(比如远程桌面唤醒),而且 GetAsyncKeyState 在服务进程里根本不可靠。Windows 提供了会话状态变更通知机制,这才是正路。

关键点:必须在 UI 线程注册,且窗口需处理 WM_WTSSESSION_CHANGE 消息;不能在无窗口的控制台程序或服务里直接用(除非自己创建隐藏窗口)。

  • WTSRegisterSessionNotification 需传入一个 HWND,所以哪怕你写的是控制台程序,也得创建一个不可见窗口(用 CreateWindowEx + WS_POPUP)
  • 注册后,锁屏/解锁会发 WM_WTSSESSION_CHANGE,wParam 是 WTS_SESSION_LOCK 或 WTS_SESSION_UNLOCK
  • 别忘了调用 WTSUnregisterSessionNotification 清理,否则下次注册失败
  • 注意:该 API 从 Windows XP 开始支持,但 Vista+ 才稳定;Win7 及以后无需管理员权限

macOS 怎么拿到屏幕锁定事件?靠 CGSession + IORegistry 监听,不是 ScreenSaver 框架

macOS 没有类似 Windows 的会话通知,ScreenSaver 框架只管屏保启动,和系统锁屏(如 Cmd+Ctrl+Q)无关。真实锁屏由 loginwindow 进程触发,信号藏在 IOKit 的 IORegistry 里,同时 CGSession 提供轻量级轮询接口。

推荐组合:用 CGSessionCopyCurrentDictionary 获取当前会话状态(含 kCGSessionOnConsoleKey 和 kCGSessionIsLockedKey),再配合 IOPMConnectionCreate 监听电源/显示状态变化作为辅助判断。

立即学习“C++免费学习笔记(深入)”;

Windows-Android_SSH_Remote_Control
Windows-Android_SSH_Remote_Control

通过 SSH 隧道从 Android 设备在互联网上对 Windows PC 实现完整远程控制的设置与使用指南,适用于远程桌面访问、安全 RDP 等。

下载
  • CGSessionCopyCurrentDictionary 返回字典,查 kCGSessionIsLockedKey 的布尔值即可,每秒查一次足够(别高频调用)
  • 纯监听方案要用 IOServiceAddInterestNotification 订阅 IOPlatformExpertDevice 的 IOGeneralInterest,但实现复杂、易漏事件
  • 注意:沙盒应用无法访问 CGSession API,需在 entitlements 中添加 com.apple.security.temporary-exception.mach-lookup.global-name(不推荐)或改用无沙盒进程协作
  • macOS 12+ 对 CGSession 的调用更敏感,建议加 @autoreleasepool 防止内存泄漏(C++ 混编 ObjC 时)

Linux 下没有统一锁屏 API,logind D-Bus 接口是唯一靠谱选择

X11 或 Wayland 自身都不暴露锁屏状态,桌面环境(GNOME/KDE)各自为政。唯一跨桌面的途径是通过 systemd-logind 的 D-Bus 接口,它由 logind 守护进程统一管理会话生命周期。

重点监听 org.freedesktop.login1.Manager 的 LockSession 和 UnlockSession 信号,或者轮询 GetSession 方法返回的 LockedHint 属性。

  • 必须连接到系统总线(dbus_system_bus_get),不是会话总线;普通用户默认有权限,但某些发行版(如 RHEL/CentOS)需在 /etc/dbus-1/system.d/ 配置策略
  • 信号监听比轮询更及时,但首次连接后要先调用 ListSessions 获取当前状态,避免启动时错过初始锁态
  • Wayland 下部分场景(如 GNOME 的 “锁屏后黑屏”)可能延迟几秒才发出信号,建议加 500ms 去抖
  • 别依赖 XScreenSaverQueryInfo —— 它只反映屏保,且在 Wayland 上完全失效

C++ 跨平台封装要注意什么?别把平台逻辑塞进同一个函数里

最常见错误是写一个 isSystemLocked() 函数,里面用 #ifdef 堆砌三套逻辑,结果 Windows 编译过、macOS 运行崩溃、Linux 测试时发现 D-Bus 连接超时没处理。

真正可行的做法是分层:抽象出 LockStateObserver 接口,每个平台实现独立类(WindowsLockObserver、MacOSSessionObserver、LinuxLogindObserver),初始化时动态选型。

  • 各平台初始化失败(如 macOS 没权限、Linux D-Bus 不可用)必须返回明确错误,不能静默降级为“始终未锁屏”
  • 锁屏状态不是瞬时值,而是带时间戳的事件流;缓存最新状态 + 更新时间,避免频繁查询引发性能抖动
  • Windows 的 WM_WTSSESSION_CHANGE 可能被其他消息淹没,确保消息循环不阻塞;macOS 的 CGSession 调用要放在主线程(GCD main queue);Linux 的 D-Bus 回调必须用异步 dispatch 避免阻塞主循环
  • 测试时最容易忽略的是“锁屏中重启”场景:Windows 会话可能变成 WTSDisconnected,macOS 会话字典可能为空,Linux 的 logind 会话 ID 可能重置——这些都要单独处理

热门AI工具

更多
WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

超级简历WonderCV

一款AI办公效率工具,主要用于免费求职简历模版下载制作,应届生职场人必备简历制作神器,适合需要提升相关任务效率的用户。

Lovart
Lovart Hot

一款面向视觉设计创作的AI设计平台,可通过智能体和画布工作流辅助制作海报、Logo、网页、PPT及其他视觉内容。

Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

咔片AIPPT

一款在线AI演示文稿制作工具,可根据主题和内容需求辅助生成PPT结构与页面,提高演示材料制作效率。

SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

相关专题

更多
硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

3148

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

4949

2025.10.17

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

3789

2025.12.29

java接口相关教程
java接口相关教程

本专题整合了java接口相关内容,阅读专题下面的文章了解更多详细内容。

446

2026.01.19

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

5927

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

2528

2023.08.10

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

4258

2023.08.10

windows查看端口占用情况
windows查看端口占用情况

Windows端口可以认为是计算机与外界通讯交流的出入口。逻辑意义上的端口一般是指TCP/IP协议中的端口,端口号的范围从0到65535,比如用于浏览网页服务的80端口,用于FTP服务的21端口等等。怎么查看windows端口占用情况呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

3259

2023.07.26

Gradle插件开发入门教程
Gradle插件开发入门教程

本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。

0

2026.10.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Python uv官方安装与入门文档
Python uv官方安装与入门文档

共0课时 | 0人学习

Buffalo框架快速入门指南
Buffalo框架快速入门指南

共0课时 | 0人学习

Conan 2 安装指南
Conan 2 安装指南

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn