在 Mac OSX 上接收电源通知(尤其是关机)
我正在用 C 语言为 Mac(Leopard)编写一个应用程序,它需要在收到电源通知时执行一些工作,例如睡眠、唤醒、关机、重新启动。它在登录时通过 launchd
作为启动代理运行,然后开始监视通知。我用来执行此操作的代码如下:
/* ask for power notifications */
static void StartPowerNotification(void)
{
static io_connect_t rootPort;
IONotificationPortRef notificationPort;
io_object_t notifier;
rootPort = IORegisterForSystemPower(&rootPort, ¬ificationPort,
PowerCallback, ¬ifier);
if (!rootPort)
exit (1);
CFRunLoopAddSource (CFRunLoopGetCurrent(),
IONotificationPortGetRunLoopSource(notificationPort),
kCFRunLoopDefaultMode);
}
/* perform actions on receipt of power notifications */
void PowerCallback (void *rootPort, io_service_t y,
natural_t msgType, void *msgArgument)
{
switch (msgType)
{
case kIOMessageSystemWillSleep:
/* perform sleep actions */
break;
case kIOMessageSystemHasPoweredOn:
/* perform wakeup actions */
break;
case kIOMessageSystemWillRestart:
/* perform restart actions */
break;
case kIOMessageSystemWillPowerOff:
/* perform shutdown actions */
break;
}
}
但是,只有前两个用于睡眠和唤醒(kIOMessageSystemWillSleep
和 kIOMessageSystemHasPoweredOn
)曾经接到电话。我从未收到任何重新启动或关闭的通知(kIOMessageSystemWillRestart
和 kIOMessageSystemWillPowerOff
)。
我做错了什么吗?或者是否有另一个 API 可以给我重新启动和关闭通知?我更愿意将其保留为 C 程序(因为这就是我所熟悉的),但对任何明智的替代方案建议持开放态度(我已经查看过登录/注销挂钩,但这些似乎已被弃用)发射的d)。
预先感谢您的任何帮助/提示!
I'm writing an application in C for the Mac (Leopard) that needs to do some work on receipt of power notifications, e.g. sleep, wake-up, shutdown, restart. It runs via launchd
as a launchagent on login then begins monitoring for notifications. The code I'm using to do this is as follows:
/* ask for power notifications */
static void StartPowerNotification(void)
{
static io_connect_t rootPort;
IONotificationPortRef notificationPort;
io_object_t notifier;
rootPort = IORegisterForSystemPower(&rootPort, ¬ificationPort,
PowerCallback, ¬ifier);
if (!rootPort)
exit (1);
CFRunLoopAddSource (CFRunLoopGetCurrent(),
IONotificationPortGetRunLoopSource(notificationPort),
kCFRunLoopDefaultMode);
}
/* perform actions on receipt of power notifications */
void PowerCallback (void *rootPort, io_service_t y,
natural_t msgType, void *msgArgument)
{
switch (msgType)
{
case kIOMessageSystemWillSleep:
/* perform sleep actions */
break;
case kIOMessageSystemHasPoweredOn:
/* perform wakeup actions */
break;
case kIOMessageSystemWillRestart:
/* perform restart actions */
break;
case kIOMessageSystemWillPowerOff:
/* perform shutdown actions */
break;
}
}
However, only the top two for sleep and wake (kIOMessageSystemWillSleep
and kIOMessageSystemHasPoweredOn
) ever get called. I never get any notifcations for restart or shutdown (kIOMessageSystemWillRestart
and kIOMessageSystemWillPowerOff
).
Am I doing something wrong? Or is there another API that would give me the restart and shutdown notifications? I'd prefer to keep it as a C program (as thats what I'm familiar with) but am open to any sensible suggestions of alternatives (I've had a look at login/logout hooks but these seem to be deprecated in favour of launchd).
Thanks in advance for any help/tips!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我知道您可以从 NSWorkspace 注册 NSWorkspaceWillPowerOffNotification 通知,这不是 C 函数,但确实有效。
然后在 WorkspaceResponder.m 中:
I know you can register for the NSWorkspaceWillPowerOffNotification notification from NSWorkspace, which is not a C function but does work.
Then in WorkspaceResponder.m:
使用 IORegisterForSystemPower 不会提供您寻求的事件。引用函数文档:
Using
IORegisterForSystemPower
doesn't provide the events you seek. Quoting from function documentation :