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
  • Select an option

  • Save WardsParadox/d6a8fbe0c0d1f100b5574188e4bd627d to your computer and use it in GitHub Desktop.

Select an option

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()
@07-C9

07-C9 commented Dec 20, 2022

Copy link
Copy Markdown

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