我找不到任何有关如何将Mac以编程方式置于睡眠模式的指令(在Objective-C中)。我确定它应该只有一行,但你可以给我一个提示吗?
答案 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
数组中,并且显然,当前登录的用户始终在那里。