Выполнить определенные системные события, Mac OS X - PullRequest
4 голосов
/ 24 мая 2011

Я бы хотел

  • Shutdown
  • Перезапуск
  • Logoff
  • Sleep

Моя система через приложение, которое я делаю, похоже, я не могу найти какой-либо собственный способ 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 ]

11 голосов
/ 24 мая 2011

Я использую следующий код более 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;
}

Обратите внимание, что приведенный выше код основан на коде из Технических вопросов и ответов QA1134 , но мой переработан для использования AESendMessage() вместо AESend().AESend() находится в HIToolbox.framework, то есть в Carbon.framework и поэтому недоступно для 64-битных приложений.(AESendMessage() является частью AE.framework в CoreServices).

0 голосов
/ 24 мая 2011

Это определенно должно работать , если вы вошли в систему из сеанса GUI .

Это не будет работать, если вы вошли только из сеанса ssh и т. Д., БезGUI.

Пожалуйста, опишите вашу ситуацию более полно, какую ошибку вы допустили и т. д. В противном случае мы вам не поможем.

...