问题描述
有没有办法检查屏幕是否被shell或applescript锁定?不仅检查屏幕保护程序是否正在运行,而且屏幕被节能设置或按 (++).
Is there any way to check if screen is locked in shell or applescript?Not just check if screensaver is running, but screen is locked by energy saver settings or by pressing (++).
提前致谢.
推荐答案
首先,您的问题有点混乱.Shift+Control+Eject 和 Energy Saver 都会让屏幕进入睡眠状态,这与锁定屏幕不同.根据您的其他设置,这也可能需要锁定屏幕,但这是一个单独的问题.IIRC,在 Lion 上,默认情况下,没有人会锁定屏幕——但如果你让屏幕休眠的时间超过安全和设置的时间;隐私,将其锁定.
First, there's a bit of confusion in your question. Both Shift+Control+Eject and Energy Saver put the screens to sleep, which isn't the same thing as locking them. Depending on your other settings, this may also entail locking the screen, but that's a separate issue. IIRC, on Lion, by default, neither one will ever lock the screen—but if you leave the screen asleep for longer than the time set in Security & Privacy, that will lock it.
无论如何,API CGSessionCopyCurrentDictionary
允许您为 GUI 会话获取有关屏幕睡眠和屏幕锁定的信息.如果您没有 GUI 会话(例如,因为您在 ssh shell 中运行),或者您的会话不拥有控制台(例如,因为有人快速用户将您切换出去),您将不会无法获得此信息,但您至少可以检测到这些情况.
Anyway, the API CGSessionCopyCurrentDictionary
allows you to get information about both screen sleep and screen lock, for your GUI session. If you don't have a GUI session (e.g., because you're running in an ssh shell), or your session doesn't own the console (e.g., because someone has fast-user-switched you out), you won't be able to get this information, but you will at least be able to detect those cases.
这是我所知道的唯一一种适用于从 10.5(实际上是 10.3)到 10.8 的所有操作系统的机制(但这并不意味着它实际上是唯一的......).
This is the only mechanism I know of that works for all OS's from 10.5 (actually 10.3) to 10.8 (but that doesn't mean it's the only one there actually is…).
没有直接的方法可以从 bash 或 AppleScript 调用它.但是,您可以使用您喜欢的桥接器(PyObjC、MacRuby、ASOC 等)来间接调用它.这是一个使用 Python 的示例:
There's no direct way to call this from bash or AppleScript. However, you can use your favorite bridge (PyObjC, MacRuby, ASOC, etc.) to call it indirectly. Here's an example using Python:
#!/usr/bin/python
import Quartz
d = Quartz.CGSessionCopyCurrentDictionary()
print d
以下是解释响应的方法:
Here's how to interpret the response:
- 如果你什么也没得到,那么你就没有 UI 会话.
- 如果字典有
kCGSSessionOnConsoleKey
= 0,或者不存在,要么你的 GUI 会话不拥有控制台,要么控制台的屏幕处于睡眠状态. - 如果字典具有
CGSSessionScreenIsLocked
= 1,则屏幕被锁定.
- If you get nothing back, then you don't have a UI session.
- If the dictionary has
kCGSSessionOnConsoleKey
= 0, or not present, either your GUI session doesn't own the console, or the console's screens are asleep. - If the dictionary has
CGSSessionScreenIsLocked
= 1, the screens are locked.
一个问题是 kCGSSessionOnConsoleKey
为 0(或缺失)而 CGSSessionScreenIsLocked
为 1.在这种情况下,要么你让屏幕进入睡眠状态并锁定他们,或者其他人拿走了控制台并锁定了屏幕(无论是否让他们进入睡眠状态).我不确定是否有办法区分这些情况.但是,如果您正在寻找不要尝试显示对话框,因为用户必须先解锁屏幕",那么这两种情况都意味着不要显示对话框".
The one problem case is where kCGSSessionOnConsoleKey
is 0 (or missing) and CGSSessionScreenIsLocked
is 1. In that case, either you've put the screens to sleep and locked them, or someone else has taken the console and locked the screens (with or without putting them to sleep). And I'm not sure if there's a way to distinguish between these cases. But if you're looking for "don't try to display a dialog because the user will have to unlock the screen first", both of those cases mean "don't display a dialog".
所以,这应该给你你想要的:
So, this should give you what you want:
#!/usr/bin/python
import sys
import Quartz
d=Quartz.CGSessionCopyCurrentDictionary()
sys.exit(d and
d.get("CGSSessionScreenIsLocked", 0) == 0 and
d.get("kCGSSessionOnConsoleKey", 0) == 1)
或者,将其转换为单行代码,您可以直接将其放入 shell 脚本中:
Or, turning it into a one-liner you can put directly in a shell script:
python -c 'import sys,Quartz; d=Quartz.CGSessionCopyCurrentDictionary(); sys.exit(d and d.get("CGSSessionScreenIsLocked", 0) == 0 and d.get("kCGSSessionOnConsoleKey", 0) == 1)'
现在,如果您通过 ssh 连接到 Mac,并且您也当前登录到该 Mac 的 GUI 控制台(作为同一用户)怎么办?在这种情况下,您的 ssh 登录会话可以以与本地终端登录会话完全相同的方式与控制台登录会话进行通信.因此,CGSessionCopyCurrentDictionary 将获得相同的值.
Now, what if you've ssh'd into a Mac, and you're also currently logged into that Mac's GUI console (as the same user)? In that case, your ssh login session can communicate with the console login session in exactly the same way that a local Terminal login session would. So, CGSessionCopyCurrentDictionary is going to get the same values.
介导该连接的引导服务器将应用一些限制(例如,security authorize -u foo
应该在终端上工作,但不能通过 ssh),但这些没有完全记录,并更改从版本到版本,所以这可能不是你想要依赖的东西.相反,您想实际读取您的登录会话信息
The bootstrap server that mediates that connection will apply some restrictions (e.g., security authorize -u foo
should work from the Terminal but not over ssh), but those aren't fully documented, and change from version to version, so that's probably not something you want to rely on. Instead, you want to actually read your login session information
如果您想更进一步,请先阅读 多用户环境编程主题.但是有些信息并没有真正记录在任何地方(例如,SessionGetInfo
引用的 Mach 级会话和 utmpx
引用的 BSD 级会话如何绑定在一起).许多相关工具和库都是开源,这可能会有所帮助.即使阅读所有这些并没有告诉你如何做你想做的事,它会告诉你你想要什么,以及用于搜索和提问的正确术语,这可能已经足够了.
If you want to go further with this, start with reading Multiple User Environments Programming Topics. But some of the information isn't really documented anywhere (e.g., how the Mach-level sessions referenced by SessionGetInfo
and the BSD-level sessions referenced by utmpx
are tied together). Many of the relevant tools and libraries are open source, which may help. Even if reading up on all of that doesn't tell you how to do what you want, it will tell you exactly what you want, and the right terms to use to search and ask questions, which may be good enough.
这篇关于OSX:检查屏幕是否被锁定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!