Skip to content

Instantly share code, notes, and snippets.

@WardsParadox
Forked from macsimom/main.m
Last active October 24, 2023 13:03
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save WardsParadox/d6a8fbe0c0d1f100b5574188e4bd627d to your computer and use it in GitHub Desktop.
Save WardsParadox/d6a8fbe0c0d1f100b5574188e4bd627d to your computer and use it in GitHub Desktop.
openwithrosetta - a tool to check the box "Open with Rosetta" on Apple Silicon Big Sur Macs
import os
import subprocess
import sys
from Foundation import * # pylint: disable=E0611 #
import objc
from SystemConfiguration import SCDynamicStoreCopyConsoleUser
def is_arm64():
"""
Determine if a Mac can run ARM64 code, whether or not the binary is running in Rosetta 2 via pyobjc
https://gist.github.com/pudquick/ca7fa134895f30b070212ea505cab5eb
Returns:
boolean: True = arm64 device (aka Apple Silicon), False = x86_64 (Intel Silicon)
"""
CF = NSBundle.bundleWithPath_("/System/Library/Frameworks/CoreFoundation.framework")
f = [("CFBundleIsArchitectureLoadable", b"BQ")]
objc.loadBundleFunctions(CF, globals(), f)
NSBundleExecutableArchitectureARM64 = 0x0100000C
return CFBundleIsArchitectureLoadable(NSBundleExecutableArchitectureARM64)
# Shamelessly Stolen from FoundationPlist (L26-106): https://github.com/munki/munki/blob/main/code/client/munkilib/FoundationPlist.py
class NSPropertyListSerializationException(BaseException):
"""Read/parse error for plists"""
pass
class NSPropertyListWriteException(BaseException):
"""Write error for plists"""
pass
def readPlist(filepath):
"""
Read a .plist file from filepath. Return the unpacked root object
(which is usually a dictionary).
"""
plistData = NSData.dataWithContentsOfFile_(filepath)
(
dataObject,
dummy_plistFormat,
error,
) = NSPropertyListSerialization.propertyListFromData_mutabilityOption_format_errorDescription_(
plistData, NSPropertyListMutableContainers, None, None
)
if dataObject is None:
if error:
error = error.encode("ascii", "ignore")
else:
error = "Unknown error"
errmsg = "%s in file %s" % (error, filepath)
raise NSPropertyListSerializationException(errmsg)
else:
return dataObject
def readPlistFromString(data):
"""Read a plist data from a (byte)string. Return the root object."""
plistData = NSData.dataWithBytes_length_(data, len(data))
if not plistData:
raise NSPropertyListSerializationException("Could not convert string to NSData")
(
dataObject,
dummy_plistFormat,
error,
) = NSPropertyListSerialization.propertyListFromData_mutabilityOption_format_errorDescription_(
plistData, NSPropertyListMutableContainers, None, None
)
if dataObject is None:
if error:
error = error.encode("ascii", "ignore")
else:
error = "Unknown error"
raise NSPropertyListSerializationException(error)
else:
return dataObject
def writePlist(dataObject, filepath):
"""
Write 'rootObject' as a plist to filepath.
"""
(
plistData,
error,
) = NSPropertyListSerialization.dataFromPropertyList_format_errorDescription_(
dataObject, NSPropertyListXMLFormat_v1_0, None
)
if plistData is None:
if error:
error = error.encode("ascii", "ignore")
else:
error = "Unknown error"
raise NSPropertyListSerializationException(error)
else:
if plistData.writeToFile_atomically_(filepath, True):
return
else:
raise NSPropertyListWriteException(
"Failed to write plist data to %s" % filepath
)
def main():
"""Main, duh, whatelse but RUNNNN!"""
if not is_arm64():
print("Intel device detected...no problemo!")
sys.exit(0)
# Dont' rely on python knowing which user is active as we run this run sudo via jamf
name, uid, gid = SCDynamicStoreCopyConsoleUser(None, None, None)
ls_path = f"/Users/{name}/Library/Preferences/com.apple.LaunchServices/com.apple.LaunchServices.plist"
ls_mode = "x86_64"
app_path = "/Applications/Cisco/Cisco AnyConnect Secure Mobility Client.app"
if not os.path.exists(app_path)
print(f"Bad App Path given!")
sys.exit(1)
bundle_identifier = NSBundle.bundleWithPath_(app_path).bundleIdentifier()
file_path = NSURL.fileURLWithPath_(app_path)
bookmark = file_path.bookmarkDataWithOptions_includingResourceValuesForKeys_relativeToURL_error_(
NSURLBookmarkCreationSuitableForBookmarkFile, None, None, None
)
data = NSData.alloc().initWithBytes_length_(bookmark[0], len(bookmark[0]))
if os.path.exists(ls_path):
ls_data = readPlist(ls_path)
else:
dummy = plistlib.dumps({"Architectures for arm64": {}})
ls_data = readPlistFromString(dummy)
if bundle_identifier in ls_data["Architectures for arm64"]:
if ls_mode in ls_data["Architectures for arm64"][bundle_identifier]:
print(f"App bundle {bundle_identifier} already set to {ls_mode}")
sys.exit(0)
else:
print(f"Setting App bundle {bundle_identifier} to {ls_mode}")
else:
print(
f"App bundle {bundle_identifier} not found. Creating and Setting to {ls_mode}"
)
ls_data["Architectures for arm64"][bundle_identifier] = [data, ls_mode]
writePlist(ls_data, ls_path)
# Kill LaunchServices daemon to load saved data
subprocess.check_call(["/usr/bin/killall", "lsd"])
if __name__ == "__main__":
main()
@itsbradwhite
Copy link

This came in SUPER clutch. Many thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment