如何以编程方式阻止 Mac 进入睡眠状态?

发布于 2024-10-31 08:32:48 字数 209 浏览 1 评论 0原文

有没有办法使用 Objective-C 以编程方式阻止 Mac 进入睡眠状态? Apple 开发网站上的 I/O 套件基础知识部分告诉我,驱动程序会收到空闲/系统睡眠的通知,但我找不到阻止系统睡眠的方法。有可能吗?

我遇到过一些使用 Caffeine、jiggler、sleepless 甚至 AppleScript 的其他解决方案,但我想在 Objective-C 中做到这一点。谢谢。

Is there way to prevent a Mac from going to sleep programmatically using Objective-C? The I/O kit fundamentals section on Apple's dev site tells me that a driver gets notified of an idle / system sleep, but I can't find a way of preventing the system from sleeping. Is it even possible?

I've come across some other solutions using Caffeine, jiggler, sleepless and even AppleScript, but I want to do this in Objective-C. Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

似狗非友 2024-11-07 08:32:59

只需创建一个 NSTimer 来触发一个函数,

UpdateSystemActivity(OverallAct);

我很确定这正是 Caffeine 所做的。

Just create an NSTimer that fires a function with this

UpdateSystemActivity(OverallAct);

I'm pretty sure that that's exactly what Caffeine does.

栖竹 2024-11-07 08:32:58

Apple 的 Q&A1340 取代了 Q&A1160。最新的问答回答了“问:当计算机进入睡眠状态或从睡眠状态唤醒时,我的应用程序如何收到通知?如何阻止睡眠?”

Q&A1340 的清单 2:

#import <IOKit/pwr_mgt/IOPMLib.h>

// kIOPMAssertionTypeNoDisplaySleep prevents display sleep,
// kIOPMAssertionTypeNoIdleSleep prevents idle sleep

//reasonForActivity is a descriptive string used by the system whenever it needs 
//  to tell the user why the system is not sleeping. For example, 
//  "Mail Compacting Mailboxes" would be a useful string.

//  NOTE: IOPMAssertionCreateWithName limits the string to 128 characters. 
CFStringRef* reasonForActivity= CFSTR("Describe Activity Type");

IOPMAssertionID assertionID;
IOReturn success = IOPMAssertionCreateWithName(kIOPMAssertionTypeNoDisplaySleep, 
                                    kIOPMAssertionLevelOn, reasonForActivity, &assertionID); 
if (success == kIOReturnSuccess)
{

    //Add the work you need to do without 
    //  the system sleeping here.

    success = IOPMAssertionRelease(assertionID);
    //The system will be able to sleep again. 
}

请注意,您只能停止空闲时间睡眠,不是用户触发的睡眠。

对于支持 Mac OS X 10.6 及更高版本的应用程序,请使用新的 IOPMAssertion 函数系列。这些函数允许其他应用程序和实用程序看到您的应用程序不希望休眠的愿望;这对于与第三方电源管理软件无缝协作至关重要。

Apple's Q&A1340 replaces Q&A1160. The latest Q&A answers the question "Q: How can my application get notified when the computer is going to sleep or waking from sleep? How do I prevent sleep?"

Listing 2 of Q&A1340:

#import <IOKit/pwr_mgt/IOPMLib.h>

// kIOPMAssertionTypeNoDisplaySleep prevents display sleep,
// kIOPMAssertionTypeNoIdleSleep prevents idle sleep

//reasonForActivity is a descriptive string used by the system whenever it needs 
//  to tell the user why the system is not sleeping. For example, 
//  "Mail Compacting Mailboxes" would be a useful string.

//  NOTE: IOPMAssertionCreateWithName limits the string to 128 characters. 
CFStringRef* reasonForActivity= CFSTR("Describe Activity Type");

IOPMAssertionID assertionID;
IOReturn success = IOPMAssertionCreateWithName(kIOPMAssertionTypeNoDisplaySleep, 
                                    kIOPMAssertionLevelOn, reasonForActivity, &assertionID); 
if (success == kIOReturnSuccess)
{

    //Add the work you need to do without 
    //  the system sleeping here.

    success = IOPMAssertionRelease(assertionID);
    //The system will be able to sleep again. 
}

Note that you can only stop idle time sleep, not sleep triggered by the user.

For applications supporting Mac OS X 10.6 and later, use the new IOPMAssertion family of functions. These functions allow other applications and utilities to see your application's desire not to sleep; this is critical to working seamlessly with third party power management software.

白芷 2024-11-07 08:32:55

这是苹果官方文档(包括代码片段):
技术问答 QA1340 - 如何防止睡眠?

引用:在 Mac OS X 10.6 Snow Leopard 中使用 I/O Kit 防止睡眠:

#import <IOKit/pwr_mgt/IOPMLib.h>

// kIOPMAssertionTypeNoDisplaySleep prevents display sleep,
// kIOPMAssertionTypeNoIdleSleep prevents idle sleep

// reasonForActivity is a descriptive string used by the system whenever it needs 
// to tell the user why the system is not sleeping. For example, 
// "Mail Compacting Mailboxes" would be a useful string.

// NOTE: IOPMAssertionCreateWithName limits the string to 128 characters. 
CFStringRef* reasonForActivity= CFSTR("Describe Activity Type");

IOPMAssertionID assertionID;
IOReturn success = IOPMAssertionCreateWithName(kIOPMAssertionTypeNoDisplaySleep, 
                                    kIOPMAssertionLevelOn, reasonForActivity, &assertionID); 
if (success == kIOReturnSuccess)
{
    //  Add the work you need to do without 
    //  the system sleeping here.

    success = IOPMAssertionRelease(assertionID);
    //  The system will be able to sleep again. 
}

对于较旧的 OSX 版本,请检查以下内容:
技术问答 QA1160 - 如何在我的应用程序运行时防止系统睡眠正在运行?

引用: UpdateSystemActivity 的示例用法(<10.6 的规范方式)

#include <CoreServices/CoreServices.h>

void
MyTimerCallback(CFRunLoopTimerRef timer, void *info)
{
    UpdateSystemActivity(OverallAct);
}


int
main (int argc, const char * argv[])
{
    CFRunLoopTimerRef timer;
    CFRunLoopTimerContext context = { 0, NULL, NULL, NULL, NULL };

    timer = CFRunLoopTimerCreate(NULL, CFAbsoluteTimeGetCurrent(), 30, 0, 0, MyTimerCallback, &context);
    if (timer != NULL) {
        CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, kCFRunLoopCommonModes);
    }

    /* Start the run loop to receive timer callbacks. You don't need to
    call this if you already have a Carbon or Cocoa EventLoop running. */
    CFRunLoopRun();

    CFRunLoopTimerInvalidate(timer);
    CFRelease(timer);

    return (0);
}

Here is the official Apple documentation (including code snippet):
Technical Q&A QA1340 - How to I prevent sleep?

Quote: Preventing sleep using I/O Kit in Mac OS X 10.6 Snow Leopard:

#import <IOKit/pwr_mgt/IOPMLib.h>

// kIOPMAssertionTypeNoDisplaySleep prevents display sleep,
// kIOPMAssertionTypeNoIdleSleep prevents idle sleep

// reasonForActivity is a descriptive string used by the system whenever it needs 
// to tell the user why the system is not sleeping. For example, 
// "Mail Compacting Mailboxes" would be a useful string.

// NOTE: IOPMAssertionCreateWithName limits the string to 128 characters. 
CFStringRef* reasonForActivity= CFSTR("Describe Activity Type");

IOPMAssertionID assertionID;
IOReturn success = IOPMAssertionCreateWithName(kIOPMAssertionTypeNoDisplaySleep, 
                                    kIOPMAssertionLevelOn, reasonForActivity, &assertionID); 
if (success == kIOReturnSuccess)
{
    //  Add the work you need to do without 
    //  the system sleeping here.

    success = IOPMAssertionRelease(assertionID);
    //  The system will be able to sleep again. 
}

For older OSX version, check the following:
Technical Q&A QA1160 - How can I prevent system sleep while my application is running?

Quote: Example usage of UpdateSystemActivity (the canonical way for < 10.6)

#include <CoreServices/CoreServices.h>

void
MyTimerCallback(CFRunLoopTimerRef timer, void *info)
{
    UpdateSystemActivity(OverallAct);
}


int
main (int argc, const char * argv[])
{
    CFRunLoopTimerRef timer;
    CFRunLoopTimerContext context = { 0, NULL, NULL, NULL, NULL };

    timer = CFRunLoopTimerCreate(NULL, CFAbsoluteTimeGetCurrent(), 30, 0, 0, MyTimerCallback, &context);
    if (timer != NULL) {
        CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, kCFRunLoopCommonModes);
    }

    /* Start the run loop to receive timer callbacks. You don't need to
    call this if you already have a Carbon or Cocoa EventLoop running. */
    CFRunLoopRun();

    CFRunLoopTimerInvalidate(timer);
    CFRelease(timer);

    return (0);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文