4

I would like to

  • Shutdown
  • Restart
  • Logoff
  • Sleep

My system through an application I'm making, I can't seem to find any native Objective C way to do it and it's really tough.

Can anyone guide me on the best way to do this:

I have tried:

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]) {
    //
}

That had no luck at all, also tried:

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];
}

With no luck

Abizern
  • 146,289
  • 39
  • 203
  • 257
Sandeep Bansal
  • 6,280
  • 17
  • 84
  • 126
  • 1
    possible duplicate of [Shutdown Mac Objective C](http://stackoverflow.com/questions/4505632/shutdown-mac-objective-c) – jscs May 23 '11 at 23:03
  • 2
    Technical Q&A 1134 should be helpful: http://developer.apple.com/library/mac/#qa/qa1134/_index.html – jscs May 23 '11 at 23:08
  • Hi Josh. I posted the first question actually. Totally forgot about it. I have tried all methods listed including the q&a one with no luck – Sandeep Bansal May 23 '11 at 23:19

2 Answers2

11

I've been using the following code for over 8 years without issues:

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;
}

Note that the above code is based on the code from Technical Q&A QA1134, but mine is re-worked to use AESendMessage() rather than AESend(). AESend() is in HIToolbox.framework, which is in Carbon.framework and is therefore unavailable to 64-bit apps. (AESendMessage() is part of the AE.framework in CoreServices).

NSGod
  • 22,699
  • 3
  • 58
  • 66
  • It didn't work for me :(. Using this fuction with any of the actions will give the status, when calling AESendMessage, of -600 `["procNotFound"]("no eligible process with specified descriptor")` Any ideas why? – Alex Sep 27 '11 at 19:34
  • This works perfect without sandboxing. But once SandBoxing is ON it is not working. Can anyone tell me what are the entitlements to be enabled to get it work. – Jeba Moses Jun 08 '17 at 11:16
0

That should definitely work if you are logged on from a GUI session.

It won't work if you're only logged on from the ssh session etc, without the GUI.

Please describe your situation more fully, what kind of error you got, etc. Otherwise we can't help you.

Yuji
  • 34,103
  • 3
  • 70
  • 88
  • 1
    I receive no error at all. I have correctly wired everything up in interface builder. Assigned the methods and everything. But when it comes to the part where the code executes. Nothing happens. And yes the application will be running on a GUI based app. – Sandeep Bansal May 24 '11 at 00:17