-
-
Save jhbush/010bff3785beb500c2c7460aa4e23398 to your computer and use it in GitHub Desktop.
Send polite Logout / "really" Logout / Restart / Shutdown Apple Events to loginwindow via python and pyObjC
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import struct, objc | |
from Foundation import NSBundle | |
from Cocoa import NSAppleEventDescriptor | |
def OSType(s): | |
# Convert 4 character code into 4 byte integer | |
return struct.unpack('>I', s)[0] | |
# Create an opaque pointer type to mask the raw AEDesc pointers we'll throw around | |
AEDescRef = objc.createOpaquePointerType('AEDescRef', '^{AEDesc=I^^{OpaqueAEDataStorageType}}') | |
# Load AESendMessage from AE.framework for sending the AppleEvent | |
AE_bundle = NSBundle.bundleWithIdentifier_('com.apple.AE') | |
functions = [("AESendMessage", b"i^{AEDesc=I^^{OpaqueAEDataStorageType}}^{AEDesc=I^^{OpaqueAEDataStorageType}}iq"),] | |
objc.loadBundleFunctions(AE_bundle, globals(), functions) | |
# defined in AEDataModel.h | |
kAENoReply = 1 | |
kAENeverInteract = 16 | |
kAEDefaultTimeout = -1 | |
kAnyTransactionID = 0 | |
kAutoGenerateReturnID = -1 | |
# defined in AEDataModel.h | |
typeAppleEvent = OSType('aevt') | |
typeApplicationBundleID = OSType('bund') | |
# defined in AERegistry.h | |
kAELogOut = OSType('logo') | |
kAEReallyLogOut = OSType('rlgo') | |
kAEShowRestartDialog = OSType('rrst') | |
kAEShowShutdownDialog = OSType('rsdn') | |
# Build a standalone application descriptor by bundle id | |
loginwindowDesc = NSAppleEventDescriptor.alloc().initWithDescriptorType_data_(typeApplicationBundleID, buffer('com.apple.loginwindow')) | |
# build an event descriptor with our app descriptor as the target and the kAELogOut eventID | |
event = NSAppleEventDescriptor.appleEventWithEventClass_eventID_targetDescriptor_returnID_transactionID_( | |
typeAppleEvent, kAELogOut, loginwindowDesc, kAutoGenerateReturnID, kAnyTransactionID) | |
eventDesc = event.aeDesc() | |
# Send a polite logout (returns immediately) | |
err = AESendMessage(eventDesc, None, kAENoReply|kAENeverInteract, kAEDefaultTimeout) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment