通过 macOS Accessibility API 请求辅助权限时出现段错误

问题描述 投票:0回答:1

我正在尝试创建一个 Rust 程序,它将在 macOS 上请求可访问权限。

如果授予权限(通过“设置”->“隐私和安全”->“辅助功能”),则它会起作用并从

AXIsProcessTrustedWithOptions
返回 true。

但是如果不允许权限,程序不会提示请求权限,而是会因段错误而崩溃。

似乎设置字典创建不正确,但我不确定为什么。

我按照 AXIsProcessTrustedWithOptions Apple 文档创建了它,并在 macOS 14.4.1(Apple 芯片)上进行了测试。

use accessibility_sys::AXIsProcessTrustedWithOptions;
use core_foundation_sys::base::{CFRelease, TCFTypeRef};
use core_foundation_sys::dictionary::{CFDictionaryAddValue, CFDictionaryCreateMutable};
use core_foundation_sys::number::kCFBooleanTrue;
use std::ffi::CString;
use std::ptr;

fn main() {
    let mut is_allowed = false;
    unsafe {
        let options =
            CFDictionaryCreateMutable(ptr::null_mut(), 1, std::ptr::null(), std::ptr::null());
        let key = CString::new("AXTrustedCheckOptionPrompt").unwrap();
        let value = kCFBooleanTrue;
        CFDictionaryAddValue(options, key.as_ptr().as_void_ptr(), value.as_void_ptr());
        is_allowed = AXIsProcessTrustedWithOptions(options);
        CFRelease(options as *const _);
    }
    println!("Accessibility permission enabled: {}", is_allowed);
}
macos rust cocoa ffi core-foundation
1个回答
0
投票

感谢评论中的帮助,我使用

accessibility_sys::kAXTrustedCheckOptionPrompt
而不是我自己的 CString,现在它不会崩溃!还添加了错误处理

use std::{error::Error, ptr};
use accessibility_sys::{kAXTrustedCheckOptionPrompt, AXIsProcessTrustedWithOptions};
use core_foundation_sys::dictionary::{CFDictionaryAddValue, CFDictionaryCreateMutable};
use core_foundation_sys::base::{CFRelease, TCFTypeRef};
use core_foundation_sys::number::{kCFBooleanFalse, kCFBooleanTrue};


fn check_accessibility(ask_if_not_allowed: bool) -> Result<bool, Box<dyn Error>> {
    let is_allowed;
    unsafe {
        let options =
            CFDictionaryCreateMutable(ptr::null_mut(), 0, std::ptr::null(), std::ptr::null());
        let key = kAXTrustedCheckOptionPrompt;
        let value = if ask_if_not_allowed {kCFBooleanTrue} else {kCFBooleanFalse};
        if !options.is_null() {
            CFDictionaryAddValue(
                options,
                key.as_void_ptr(),
                value.as_void_ptr(),
            );
            is_allowed = AXIsProcessTrustedWithOptions(options);
            CFRelease(options as *const _);
        } else {
            return Err("options is null".into());
        }
    }
    Ok(is_allowed)
}

fn main() {
    let is_allowed = check_accessibility(true).unwrap();
    println!("Accessibility permission enabled: {}", is_allowed);
}
© www.soinside.com 2019 - 2024. All rights reserved.