以编程方式让Mac进入睡眠状态

时间:2011-06-05 13:17:42

标签: objective-c cocoa macos sleep

我找不到任何有关如何将Mac以编程方式置于睡眠模式的指令(在Objective-C中)。我确定它应该只有一行,但你可以给我一个提示吗?

6 个答案:

答案 0 :(得分:9)

#include <stdio.h> 
#include <CoreServices/CoreServices.h>
#include <Carbon/Carbon.h>

SendAppleEventToSystemProcess(kAESleep);

OSStatus SendAppleEventToSystemProcess(AEEventID EventToSend)
{
    AEAddressDesc targetDesc;
    static const ProcessSerialNumber kPSNOfSystemProcess = { 0, kSystemProcess };
    AppleEvent eventReply = {typeNull, NULL};
    AppleEvent appleEventToSend = {typeNull, NULL};

    OSStatus error = noErr;

    error = AECreateDesc(typeProcessSerialNumber, &kPSNOfSystemProcess, 
                                            sizeof(kPSNOfSystemProcess), &targetDesc);

    if (error != noErr)
    {
        return(error);
    }

    error = AECreateAppleEvent(kCoreEventClass, EventToSend, &targetDesc, 
                   kAutoGenerateReturnID, kAnyTransactionID, &appleEventToSend);

    AEDisposeDesc(&targetDesc);
    if (error != noErr)
    {
        return(error);
    }

    error = AESend(&appleEventToSend, &eventReply, kAENoReply, 
                  kAENormalPriority, kAEDefaultTimeout, NULL, NULL);

    AEDisposeDesc(&appleEventToSend);
    if (error != noErr)
    {
        return(error);
    }

    AEDisposeDesc(&eventReply);

    return(error); 
}

有关https://developer.apple.com/library/content/qa/qa1134/_index.html

的更多详情

答案 1 :(得分:8)

您还可以使用脚本桥。草案代码是

SystemEventsApplication *systemEvents = [SBApplication applicationWithBundleIdentifier:@"com.apple.systemevents"];
[systemEvents sleep]; 

答案 2 :(得分:7)

汤姆是对的。如果显示器处于休眠状态,AE方法将失败。 pmset sleepnow 100%工作。

NSTask  *pmsetTask = [[NSTask alloc] init];
pmsetTask.launchPath = @"/usr/bin/pmset";
pmsetTask.arguments = @[@"sleepnow"];
[pmsetTask launch];

答案 3 :(得分:6)

您可以使用AppleScript

NSAppleScript *script = [[NSAppleScript alloc] initWithSource:@"tell application \"System Events\" to sleep"];
NSDictionary *errorInfo;
[script executeAndReturnError:&errorInfo];
[script release];

答案 4 :(得分:1)

我发现在屏幕保护程序中运行pmset sleepnow,而前两个答案没有。

答案 5 :(得分:1)

以防万一有人好奇pmset sleepnow的实际工作方式-它使用IOKit框架“电源管理”部分中的IOPMSleepSystem API。您可以通过检查pmset.c source code(来自macOS 10.13.3的链接)进行检查。

因此,您可以通过以下代码段请求睡眠,而无需致电pmset

#include <IOKit/pwr_mgt/IOPMLib.h>

void SleepNow()
{
    io_connect_t fb = IOPMFindPowerManagement(MACH_PORT_NULL);
    if (fb != MACH_PORT_NULL)
    {
        IOPMSleepSystem(fb);
        IOServiceClose(fb);
    }
}

请不要担心调用者一定是root用户或控制台用户 注释,因为它似乎适用于任何标准登录用户。 / p>

通过遵循源代码,看起来它使用IOUserClient::clientHasPrivilege调用kIOClientPrivilegeLocalUser,最终检查了调用者是否存在于根IORegistry条目的IOConsoleUsers数组中,并且显然,当前登录的用户始终在那里。