-->

Finder Scripting Bridge to Shutdown

2020-08-02 03:01发布

问题:

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…

回答1:

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).



回答2:

If Scripting Bridge isn't sufficient to do something non-application specific, like shutting down the Mac, then you have the luxury of moving to other frameworks that Applescript (and by extension Scripting Bridge) doesn't have direct access to. For shutting down the Mac, see Core Services: Technical Q&A QA1134: Programmatically causing restart, shutdown and/or logout