macOS:模拟鼠标事件仅在启动二进制文件时有效,不适用于应用程序包
macOS: simulated mouse event only works when launching binary, not application bundle
我有以下代码将鼠标光标移动到 Mac:
void moveCursorPos()
{
CGPoint ppos;
ppos.x = 100;
ppos.y = 100;
CGEventRef e = CGEventCreateMouseEvent(nullptr, kCGEventMouseMoved, ppos, kCGMouseButtonLeft);
CGEventPost(kCGHIDEventTap, e);
CFRelease(e);
}
当我 运行 我的软件直接从它的二进制文件时它工作 - 例如./foo.app/Contents/MacOS/foo
。
当我通过 open foo.app
启动它时它不起作用。
做 open ./foo.app/Contents/MacOS/foo
工作。
我第一次启动它并调用该函数时,macOS 要求我允许使用可访问性 API(或类似的东西),我同意了 - 如果我转到 "Accessibility > Privacy" 窗格macOS 的安全设置,所有复选框都被选中,所有内容都被授予 foo
,等等...
- 如何在我的机器上修复它?
- 我可以在代码方面做些什么,以便我的软件用户永远不会遇到该问题,因为它破坏了我软件的核心 UI 交互?
如何在我的机器上修复它?
这真的取决于你做了什么。当我 运行 一个来自 Xcode 的应用程序时,我通常会破坏这些东西,分发,...并且它们都具有相同的包标识符(系统偏好设置中的一个条目,但周围有更多二进制文件)。
要为您的应用重置辅助功能,只需 运行:
sudo tccutil reset Accessibility com.your.bundle.Identifier
它将重置所有出现的二进制文件的辅助功能设置,您可以重新开始。
我可以在代码方面做些什么,以便我的软件用户永远不会遇到该问题,因为它破坏了我软件的核心 UI 交互?
在您的 AppDelegate.applicationDidFinishLaunching
中执行以下操作:
acquireAccessibilityPrivileges(acquired: {
self.moveCursorPos()
}, nope: {
NSApp.terminate(self)
})
其他功能:
func acquireAccessibilityPrivileges(acquired: @escaping () -> Void, nope: @escaping () -> Void) {
let options = [kAXTrustedCheckOptionPrompt.takeUnretainedValue(): true]
let enabled = AXIsProcessTrustedWithOptions(options as CFDictionary)
if enabled {
acquired()
} else {
let alert = NSAlert()
alert.messageText = "Enable XYZ"
alert.informativeText = "Click OK once you enabled XYZ in System Preferences - ..."
alert.beginSheetModal(for: self.window, completionHandler: { response in
if AXIsProcessTrustedWithOptions(options as CFDictionary) {
acquired()
} else {
nope()
}
})
}
}
func moveCursorPos() {
let event = CGEvent(mouseEventSource: nil, mouseType: .mouseMoved, mouseCursorPosition: CGPoint(x: 100, y: 100), mouseButton: .left)
event?.post(tap: .cghidEventTap)
}
open foo.app
对比 ./foo
还有一件事需要注意 - open foo.app
、./foo.app/Contents/MacOS/foo
、...
之间的区别
open Foo.app
:
Foo.app
需要此辅助功能权限
-+= 00001 root /sbin/launchd
|--= 83677 zrzka /Users/zrzka/Desktop/Foo.app/Contents/MacOS/Foo
Foo.app/Contents/MacOS/Foo
:
Iterm.app
需要此辅助功能权限
-+= 00001 root /sbin/launchd
|-+= 53984 zrzka /Applications/iTerm.app/Contents/MacOS/iTerm2
| |-+= 53986 zrzka /Applications/iTerm.app/Contents/MacOS/iTerm2 --server /usr/bin/login -fpl zrzka /Applications/iTerm.app/Contents/MacOS/iTerm2 --launch_shell
| | \-+= 53987 root /usr/bin/login -fpl zrzka /Applications/iTerm.app/Contents/MacOS/iTerm2 --launch_shell
| | \-+= 53988 zrzka -zsh
| | \--= 84461 zrzka Foo.app/Contents/MacOS/Foo
open Foo.app/Contents/MacOS/Foo
:
Terminal.app
已启动,其中有 Foo
- 那是因为我确实使用 iTerm,但默认的是 Terminal
Terminal.app
需要此辅助功能权限
-+= 00001 root /sbin/launchd
|-+= 73320 zrzka /System/Applications/Utilities/Terminal.app/Contents/MacOS/Terminal
| \-+= 75674 root login -pf zrzka
| \-+= 75679 zrzka -zsh
| \--= 75717 zrzka /Users/zrzka/Desktop/Foo.app/Contents/MacOS/Foo
更多提示
有时,我的应用程序不再出现在系统偏好设置 - 安全和隐私 - 辅助功能中。我不知道为什么,但它与我的 tccutil
重置有某种联系。打开 Finder 并将 Foo.app
拖放到窗格中。
我有以下代码将鼠标光标移动到 Mac:
void moveCursorPos()
{
CGPoint ppos;
ppos.x = 100;
ppos.y = 100;
CGEventRef e = CGEventCreateMouseEvent(nullptr, kCGEventMouseMoved, ppos, kCGMouseButtonLeft);
CGEventPost(kCGHIDEventTap, e);
CFRelease(e);
}
当我 运行 我的软件直接从它的二进制文件时它工作 - 例如./foo.app/Contents/MacOS/foo
。
当我通过 open foo.app
启动它时它不起作用。
做 open ./foo.app/Contents/MacOS/foo
工作。
我第一次启动它并调用该函数时,macOS 要求我允许使用可访问性 API(或类似的东西),我同意了 - 如果我转到 "Accessibility > Privacy" 窗格macOS 的安全设置,所有复选框都被选中,所有内容都被授予 foo
,等等...
- 如何在我的机器上修复它?
- 我可以在代码方面做些什么,以便我的软件用户永远不会遇到该问题,因为它破坏了我软件的核心 UI 交互?
如何在我的机器上修复它?
这真的取决于你做了什么。当我 运行 一个来自 Xcode 的应用程序时,我通常会破坏这些东西,分发,...并且它们都具有相同的包标识符(系统偏好设置中的一个条目,但周围有更多二进制文件)。
要为您的应用重置辅助功能,只需 运行:
sudo tccutil reset Accessibility com.your.bundle.Identifier
它将重置所有出现的二进制文件的辅助功能设置,您可以重新开始。
我可以在代码方面做些什么,以便我的软件用户永远不会遇到该问题,因为它破坏了我软件的核心 UI 交互?
在您的 AppDelegate.applicationDidFinishLaunching
中执行以下操作:
acquireAccessibilityPrivileges(acquired: {
self.moveCursorPos()
}, nope: {
NSApp.terminate(self)
})
其他功能:
func acquireAccessibilityPrivileges(acquired: @escaping () -> Void, nope: @escaping () -> Void) {
let options = [kAXTrustedCheckOptionPrompt.takeUnretainedValue(): true]
let enabled = AXIsProcessTrustedWithOptions(options as CFDictionary)
if enabled {
acquired()
} else {
let alert = NSAlert()
alert.messageText = "Enable XYZ"
alert.informativeText = "Click OK once you enabled XYZ in System Preferences - ..."
alert.beginSheetModal(for: self.window, completionHandler: { response in
if AXIsProcessTrustedWithOptions(options as CFDictionary) {
acquired()
} else {
nope()
}
})
}
}
func moveCursorPos() {
let event = CGEvent(mouseEventSource: nil, mouseType: .mouseMoved, mouseCursorPosition: CGPoint(x: 100, y: 100), mouseButton: .left)
event?.post(tap: .cghidEventTap)
}
open foo.app
对比 ./foo
还有一件事需要注意 - open foo.app
、./foo.app/Contents/MacOS/foo
、...
open Foo.app
:
Foo.app
需要此辅助功能权限
-+= 00001 root /sbin/launchd
|--= 83677 zrzka /Users/zrzka/Desktop/Foo.app/Contents/MacOS/Foo
Foo.app/Contents/MacOS/Foo
:
Iterm.app
需要此辅助功能权限
-+= 00001 root /sbin/launchd
|-+= 53984 zrzka /Applications/iTerm.app/Contents/MacOS/iTerm2
| |-+= 53986 zrzka /Applications/iTerm.app/Contents/MacOS/iTerm2 --server /usr/bin/login -fpl zrzka /Applications/iTerm.app/Contents/MacOS/iTerm2 --launch_shell
| | \-+= 53987 root /usr/bin/login -fpl zrzka /Applications/iTerm.app/Contents/MacOS/iTerm2 --launch_shell
| | \-+= 53988 zrzka -zsh
| | \--= 84461 zrzka Foo.app/Contents/MacOS/Foo
open Foo.app/Contents/MacOS/Foo
:
Terminal.app
已启动,其中有Foo
- 那是因为我确实使用 iTerm,但默认的是 Terminal
Terminal.app
需要此辅助功能权限
-+= 00001 root /sbin/launchd
|-+= 73320 zrzka /System/Applications/Utilities/Terminal.app/Contents/MacOS/Terminal
| \-+= 75674 root login -pf zrzka
| \-+= 75679 zrzka -zsh
| \--= 75717 zrzka /Users/zrzka/Desktop/Foo.app/Contents/MacOS/Foo
更多提示
有时,我的应用程序不再出现在系统偏好设置 - 安全和隐私 - 辅助功能中。我不知道为什么,但它与我的 tccutil
重置有某种联系。打开 Finder 并将 Foo.app
拖放到窗格中。