Liming
Liming

Reputation: 49

Accessibility prompt issue on MacOS

I am building a python application on MacOS. It needs to access system event, so I used AXIsProcessTrustedWithOptions to prompt accessibility dialog.

import objc

if sys.platform == 'darwin':
    AS = objc.loadBundle('CoreServices', globals(), '/System/Library/Frameworks/ApplicationServices.framework')
    objc.loadBundleFunctions(AS, globals(), [('AXIsProcessTrustedWithOptions', b'Z@')])
    options = {'AXTrustedCheckOptionPrompt': True}
    trusted = AXIsProcessTrustedWithOptions(options)

    if trusted:
        print("The program has permission to access system events.")
    else:
        print("The program does not have permission to access system events.")

I built the app(Myapp 1.0.0) using Pyinstaller and all functions worked well.

The issue raises when I am building new version Myapp 1.0.1.

I already granted the accessibility for Myapp 1.0.0, but accessibility dialog appears again when I execute Myapp 1.0.1 everytime. (System seems to recognize them as different applications. But there is only one item for Myapp in accessibility dialog)

This is Myapp.spec file to run Pyinstaller.

`block_cipher = None

a = Analysis(
    ['main.py'],
    pathex=[],
    hiddenimports=[],
    hookspath=[],
    hooksconfig={},
    runtime_hooks=[],
    excludes=[],
    win_no_prefer_redirects=False,
    win_private_assemblies=False,
    cipher=block_cipher,
    noarchive=False,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)

exe = EXE(
    pyz,
    a.scripts,
    [],
    exclude_binaries=True,
    name='Myapp',
    debug=False,
    bootloader_ignore_signals=False,
    strip=False,
    upx=True,
    console=False,
    disable_windowed_traceback=False,
    argv_emulation=False,
    target_arch=None,
    codesign_identity=None,
    entitlements_file=None,
    icon=['BG Builder.icns'],
    manifest='akespec',
)
coll = COLLECT(
    exe,
    a.binaries,
    a.zipfiles,
    a.datas,
    strip=False,
    upx=True,
    upx_exclude=[],
    name='BG Builder',
)
app = BUNDLE(
    coll,
    name='Myapp.app',
    icon='Myapp.icns',
    bundle_identifier='com.mycompany.myapp',
    version='1.0.0',
    info_plist={
    'NSPrincipalClass': 'NSApplication',
    'CFBundleExecutable': 'Myapp',
    'CFBundleName': 'Myapp',
    'CFBundleDisplayName': 'Myapp',
    'NSAppleScriptEnabled': True,
    'CFBundlePackageType': 'APPL',
    'CFBundleLongVersionString': '1.0.0',
    'CFBundleShortVersionString': '1.0.0',
    'NSAppleScriptEnabled': 'true',
    'LSApplicationCategoryType': 'public.app-category.developer-tools',
    },
)`

How can Myapp 1.0.1 inherit accessibility status of Myapp 1.0.0?

Upvotes: 1

Views: 398

Answers (1)

Liming
Liming

Reputation: 49

Thank you for your consideration.

I resolved this issue. This in not related with .spec file.

When we make a new build of an application, the operating system assigns a new unique identifier to it.

The Accessibility API ties permissions to this unique identifier rather than the application itself, so each new build is seen as a different application and requires new permissions.

If we are rebuilding our application frequently and want to avoid constantly re-granting accessibility permissions, we could consider signing our app with a developer certificate.

This results in the same signature being used for all builds, which should prevent the issue of having to re-grant access every time we create a new build.

Here's what we'll need to do:

  • Create a Self-Signed Certificate. We can follow these steps if do not have an Apple Developer account:

Open Keychain Access(You can find it in the Utilities folder).

From the menu at the top, go to Keychain Access > Certificate Assistant > Create a Certificate.

Give your certificate a name (e.g., "MyAppCert"), set "Identity Type" to "Self Signed Root", "Certificate Type" to "Code Signing" and check the "Let me override defaults" checkbox.

Click "Continue" and follow the instructions to create your certificate.

  • Sign Your App with the Certificate Now you're ready to sign your app with the newly created certificate. To do this, you need to use the codesign command in Terminal like this:

codesign --deep --force --verbose --sign "MyAppCert" path/to/your/app.app

Replace "MyAppCert" with the name of your certificate and path/to/your/app.app with the actual path to your Python app.

Thank you.

Upvotes: 2

Related Questions