方法一、 使用CGEventPost(kCGHIDEventTap, push);获取辅助功能权限
CGEventSourceRef source = CGEventSourceCreate(kCGEventSourceStatePrivate);
CGEventRef push = CGEventCreateKeyboardEvent(source, 1, 0);
CGEventSetSource(push, source);
CGEventSetFlags(push, NULL);
CGEventPost(kCGHIDEventTap, push);
CFRelease(push);
CFRelease(source);
注意:Intel 架构没问题,终端输入
tccutil reset Accessibility com.niu.xxx
Successfully reset Accessibility approval status for com.niu.xxx
虽然m1 架构,也提示
tccutil reset Accessibility com.niu.xxx
Successfully reset Accessibility approval status for com.niu.xxx
但辅助功能里面,仍存在该app
方法二、使用AXIsProcessTrustedWithOptions(); 获取辅助功能权限
AppDelegate.m
#import "AppDelegate.h"
BOOL checkAccessibility(void)
{
// NSString *urlString = @"x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility";
// [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:urlString]];
/*
NSDictionary* opts = @{(__bridge id)kAXTrustedCheckOptionPrompt: @YES};
return AXIsProcessTrustedWithOptions((__bridge CFDictionaryRef)opts);
*/
const void * keys[] = { kAXTrustedCheckOptionPrompt };
const void * values[] = { kCFBooleanTrue };
CFDictionaryRef options = CFDictionaryCreate(
kCFAllocatorDefault,
keys,
values,
sizeof(keys) / sizeof(*keys),
&kCFCopyStringDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
return AXIsProcessTrustedWithOptions(options);
}
@interface AppDelegate ()
@property NSTimer* timer;
@end
@implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
// Insert code here to initialize your application
if (!checkAccessibility()) {
self.timer = [NSTimer scheduledTimerWithTimeInterval:3.0
repeats:YES
block:^(NSTimer* timer) {
[self relaunchIfProcessTrusted];
}];
}else{
NSLog(@"registering keydown mask");
[NSEvent addGlobalMonitorForEventsMatchingMask:NSEventMaskKeyDown
handler:^(NSEvent *event){
NSLog(@"keydown: %@", event.characters);
}];
}
}
- (void)relaunchIfProcessTrusted {
if (AXIsProcessTrusted()) {
if(self.timer){
NSLog(@"registering keydown mask");
[NSEvent addGlobalMonitorForEventsMatchingMask:NSEventMaskKeyDown
handler:^(NSEvent *event){
NSLog(@"keydown: %@", event.characters);
}];
[self.timer invalidate];
self.timer = nil;
}
/*
这段代码是使用 Objective-C 中的 NSTask 类创建一个新的进程。具体来说,它启动了一个与当前应用程序不共享内存空间的可执行文件,并且没有指定额外的参数。
其中,NSTask 类是 Cocoa 框架中的一个类,用于启动新进程、执行命令和处理输出等操作。launchedTaskWithLaunchPath:arguments: 是 NSTask 类中的一个类方法,它接受两个参数:路径和参数。其中,launchPath 参数指定要启动的可执行文件的路径,而 arguments 参数是一个字符串数组,用于传递给可执行文件的参数列表。在这个例子中,参数列表为空数组。
而 [[NSBundle mainBundle] executablePath] 是一个 NSBundle 类的实例方法,用于获取当前应用程序的主要可执行文件的路径。这个路径在每个应用程序中都是唯一的,可以用于查找和执行其他资源。在这个例子中,它作为启动的可执行文件的路径。
*/
// [NSTask launchedTaskWithLaunchPath:[[NSBundle mainBundle] executablePath] arguments:@[]];
// [NSApp terminate:nil];//作用是终止当前正在运行的 macOS 应用程序
}else{
}
}
@end
这种方法想要生效,必须禁用沙盒功能,需要将App Sandbox 设置成 NO
注意:
1. Mac App Store 中的应用无法获得辅助功能权限
2. Apple 沙盒应用程序不能具有该级别的控制(即完全的鼠标/窗口控制)