执行某些系统事件,Mac OS X.

时间:2011-05-23 22:57:18

标签: objective-c macos logout shutdown

我想

  • 关闭
  • 重新启动
  • 注销
  • 睡眠

我的系统通过我正在制作的应用程序,我似乎无法找到任何原生的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];
}

没有运气

2 个答案:

答案 0 :(得分:11)

我已经使用以下代码超过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()AE.framework)中CoreServices的一部分。

答案 1 :(得分:0)

如果您从GUI会话登录,那肯定应该

如果您只是在没有GUI的情况下从ssh会话等登录,它将无效。

请更全面地描述您的情况,您有什么样的错误等等。否则我们无法帮助您。