我写了一个C程序/ LaunchDaemon来检查我的MacBook是否在家(连接到我的WLAN)。如果是这样,它会禁用我的密码保护;如果没有,它就能启用它。
易。但问题是,当我把MacBook带到其他地方并禁用密码保护时,它会在没有密码保护的情况下醒来。
我对此的解决方法是:每次 进入睡眠状态时启用密码保护。
问题:有没有办法找出我的Mac准备睡觉的时间?有些中断,我可以让我的节目听吗?
答案 0 :(得分:6)
您可以使用I / O Kit执行此操作,请检查Apple的QA1340: Registering and unregistering for sleep and wake notifications。你可能也想 分析SleepWatcher实用程序源或使用/集成以满足您的需求。 从主页:
SleepWatcher 2.2(运行Mac OS X 10.5到10.8,包含源代码) 是Mac OS X的命令行工具(守护程序),用于监视睡眠,唤醒和 Mac的闲置。它可用于在Mac或Mac时执行Unix命令 在给定时间之后,Mac的显示器进入睡眠模式或唤醒 没有用户交互或用户在休息或休息后恢复活动 安装或拆卸Mac笔记本电脑的电源时。它也可以 将Mac发送到睡眠模式或检索自上次用户活动以来的时间。一个 需要掌握Unix命令行的一点知识才能从中受益 这个软件。
答案 1 :(得分:1)
我在我的 C 文件 beforesleep.c
的内容下方附加了它,当收到“将休眠”通知时,它会执行一些命令行命令(在我的例子中是 shell 命令和 AppleScript 脚本)。
为了在 Mac 进入睡眠状态时运行您的代码,只需将 system(...)
调用替换为您希望运行的代码。
就我而言,我使用 system()
,因为它允许我运行作为字符串传递的 shell 命令,但如果您更喜欢只运行 C 代码,则可以将 C 代码放在那里。
为了构建这个文件,我运行:
gcc -framework IOKit -framework Cocoa beforesleep.c
如果您要使用此代码,请确保它始终在后台运行。例如,我有一个 Cron 作业,它确保这段代码始终在运行,并且它会再次启动它,以防它因任何原因被意外杀死(尽管到目前为止它从未发生在我身上)。如果您有足够的经验,您可以找到更明智的方法来确保这一点。
有关其工作原理的更多详细信息,请参阅 this link(已由 sidyll 建议)。
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <mach/mach_port.h>
#include <mach/mach_interface.h>
#include <mach/mach_init.h>
#include <IOKit/pwr_mgt/IOPMLib.h>
#include <IOKit/IOMessage.h>
io_connect_t root_port; // a reference to the Root Power Domain IOService
void
MySleepCallBack( void * refCon, io_service_t service, natural_t messageType, void * messageArgument )
{
switch ( messageType )
{
case kIOMessageCanSystemSleep:
IOAllowPowerChange( root_port, (long)messageArgument );
break;
case kIOMessageSystemWillSleep:
system("/Users/andrea/bin/mylogger.sh");
system("osascript /Users/andrea/bin/pause_clockwork.scpt");
IOAllowPowerChange( root_port, (long)messageArgument );
break;
case kIOMessageSystemWillPowerOn:
//System has started the wake up process...
break;
case kIOMessageSystemHasPoweredOn:
//System has finished waking up...
break;
default:
break;
}
}
int main( int argc, char **argv )
{
// notification port allocated by IORegisterForSystemPower
IONotificationPortRef notifyPortRef;
// notifier object, used to deregister later
io_object_t notifierObject;
// this parameter is passed to the callback
void* refCon;
// register to receive system sleep notifications
root_port = IORegisterForSystemPower( refCon, ¬ifyPortRef, MySleepCallBack, ¬ifierObject );
if ( root_port == 0 )
{
printf("IORegisterForSystemPower failed\n");
return 1;
}
// add the notification port to the application runloop
CFRunLoopAddSource( CFRunLoopGetCurrent(),
IONotificationPortGetRunLoopSource(notifyPortRef), kCFRunLoopCommonModes );
/* Start the run loop to receive sleep notifications. Don't call CFRunLoopRun if this code
is running on the main thread of a Cocoa or Carbon application. Cocoa and Carbon
manage the main thread's run loop for you as part of their event handling
mechanisms.
*/
CFRunLoopRun();
//Not reached, CFRunLoopRun doesn't return in this case.
return (0);
}