Search code examples
objective-ccocoamacosscripting-bridge

Finder Scripting Bridge to Shutdown


I tried to use Application Scripting Bridge to send my Mac to sleep. The code look like the following:

#import "Finder.h"
 FinderApplication *Finder = [SBApplication applicationWithBundleIdentifier:@"com.apple.finder"];
        [Finder sleep];

But it doesn't work. Any ideas why it doesn't work? No compiling errors or warnings, but it doesn't work…


Solution

  • As I posted in this answer, 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).