【问题标题】:Perform certain System Events, Mac OS X执行某些系统事件,Mac OS X
【发布时间】:2011-08-31 12:43:34
【问题描述】:

我愿意

  • 关机
  • 重启
  • 注销
  • 睡觉

我的系统通过我正在制作的应用程序,我似乎找不到任何原生的 Objective C 方法来做到这一点,这真的很难。

谁能指导我最好的方法:

我试过了:

NSString *scriptAction = @"restart"; // @"restart"/@"shut down"/@"sleep"/@"log out"
NSString *scriptSource = [NSString stringWithFormat:@"tell application \"Finder\" to %@", scriptAction];
NSAppleScript *appleScript = [[[NSAppleScript alloc] initWithSource:scriptSource] autorelease];
NSDictionary *errDict = nil;
if (![appleScript executeAndReturnError:&errDict]) {
    //
}

那一点运气都没有,也试过了:

NSAppleScript* theScript = [[NSAppleScript alloc] initWithSource:
                            @"Tell application \"Finder\" to restart"];
if (theScript != NULL)
{
    NSDictionary* errDict = NULL;
    // execution of the following line ends with EXC
    if (YES == [theScript compileAndReturnError: &errDict])
    {
        [theScript executeAndReturnError: &errDict];
    }
    [theScript release];
}

没有运气

【问题讨论】:

标签: objective-c macos logout shutdown


【解决方案1】:

我已经使用以下代码超过 8 年没有问题:

MDRestartShutdownLogout.h:

#import <CoreServices/CoreServices.h>
/*
    *    kAERestart        will cause system to restart
    *    kAEShutDown       will cause system to shutdown
    *    kAEReallyLogout   will cause system to logout
    *    kAESleep          will cause system to sleep
 */
extern OSStatus MDSendAppleEventToSystemProcess(AEEventID eventToSend);

MDRestartShutdownLogout.m:

#import "MDRestartShutdownLogout.h"

OSStatus MDSendAppleEventToSystemProcess(AEEventID eventToSendID) {
    AEAddressDesc targetDesc;
    static const ProcessSerialNumber kPSNOfSystemProcess = {0, kSystemProcess };
    AppleEvent eventReply = {typeNull, NULL};
    AppleEvent eventToSend = {typeNull, NULL};

    OSStatus status = AECreateDesc(typeProcessSerialNumber,
         &kPSNOfSystemProcess, sizeof(kPSNOfSystemProcess), &targetDesc);

    if (status != noErr) return status;

    status = AECreateAppleEvent(kCoreEventClass, eventToSendID,
          &targetDesc, kAutoGenerateReturnID, kAnyTransactionID, &eventToSend);

    AEDisposeDesc(&targetDesc);

    if (status != noErr) return status;

    status = AESendMessage(&eventToSend, &eventReply,
                          kAENormalPriority, kAEDefaultTimeout);

    AEDisposeDesc(&eventToSend);
    if (status != noErr) return status;
    AEDisposeDesc(&eventReply);
    return status;
}

请注意,上面的代码是基于 Technical Q&A QA1134 的代码,但我的代码被重新设计为使用 AESendMessage() 而不是 AESend()AESend()HIToolbox.framework 中,在 Carbon.framework 中,因此对于 64 位应用程序不可用。 (AESendMessage()CoreServicesAE.framework 的一部分)。

【讨论】:

  • 它对我不起作用:(。在调用 AESendMessage 时,将这个函数与任何操作一起使用会给出 -600 ["procNotFound"]("no eligible process with specified descriptor") 任何想法为什么?
  • 这在没有沙盒的情况下完美运行。但是一旦沙盒打开它就不起作用了。谁能告诉我启用它的权利是什么。
【解决方案2】:

如果您从 GUI 会话登录,这绝对可以工作。

如果您只从ssh 会话等登录,而没有 GUI,它将无法工作。

请更全面地描述您的情况,您遇到了什么样的错误等。否则我们无法为您提供帮助。

【讨论】:

  • 我没有收到任何错误。我已经在界面生成器中正确连接了所有内容。分配方法和一切。但是当涉及到代码执行的部分时。什么都没发生。是的,该应用程序将在基于 GUI 的应用程序上运行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-07-30
  • 1970-01-01
  • 2011-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多