对于我的Mac应用程序,我有一个功能,可以在单击按钮时删除屏幕右上角的系统时钟。控制显示哪些系统菜单(包括系统时钟)的首选项存储在~/Library/Preferences/com.apple.systemuiserver.plist.中我能够更新该文件中的相关首选项,以删除系统时钟。但是,需要重新启动SystemUIServer应用程序,以便可以重新加载新的首选项并删除时钟。下面是我用来重新启动SystemUIServer的代码。
NSTask *killSystemUITask = [[NSTask alloc] init];
NSMutableArray *args = [NSMutableArray array];
[args addObject:@"SystemUIServer"];
[killSystemUITask setLaunchPath:@"/usr/bin/killall"];
[killSystemUITask setArguments:args];
[killSystemUITask launch];当SystemUIServer被杀死时,OSX会自动重启它。上面的代码可以工作,但系统时钟的删除并不像我希望的那样干净。整个系统栏会被移除一秒钟。有没有人能想出一种更好的方法来将首选项重新加载到SystemUIServer中?理想情况下,我希望系统时钟的删除与系统首选项应用程序的日期和时间首选项中的时钟显示功能一样清晰。
发布于 2011-12-28 23:38:12
您是否考虑过尝试使用AppleEvents/OSAScript来驱动首选项窗格本身?虽然Network prefs窗格似乎是唯一一个具有完全内置脚本功能的窗格,但您可以使用系统事件驱动任何UI。在AppleScript中构建原型非常容易。这是我想出来的:
tell application "System Preferences"
reveal pane "Date & Time"
reveal anchor "ClockPref" of pane "Date & Time"
tell application "System Events"
tell tab group 1 of window 1 of process "System Preferences"
repeat with cbIndex from 0 to count of checkboxes
tell checkbox cbIndex
if title contains "menu bar" then
click
exit repeat
end if
end tell
end repeat
end tell
end tell
quit
end tell您可以通过使用NSAppleScript对象原样使用它,或者如果您感到受虐待,您可以深入了解要发送的正确AppleEvents的细节。(我建议使用前一种方法,但后者在运行时执行速度会更快。)
优点:简单。
缺点:启动系统首选项(可以看到在Dock中弹出),要求启用“启用辅助设备访问”(与许多其他功能一样)
很难说这是在视觉上比杀死SystemUIServer更好还是更坏,但几乎可以肯定的是,它是对任何其他可能与SystemUIServer交互的组件更友好。
至于摆脱停靠弹出,这个question over here提到了如何让东西在没有停靠图标的情况下启动。对于这一点,我可以补充说,在过去,我一直在争论这个问题,我想出的解决方案是,在高层次上,这是:
获取一个唯一的/安全的临时目录,只制作一个硬链接镜像的整个捆绑的应用程序(pax -rwl将帮助硬链接的Info.plist的Info.plist
NSUIElement = true目录中的应用程序。当我尝试驱动第三方应用程序时,这种方法对我来说已经被证明是相当健壮的。我猜您将来可能会遇到签名/沙箱的系统应用程序的问题。(即更改他们的Info.plist会更改签名,他们可能会拒绝运行。)当然,任何沙箱应用程序都需要特定的权限或例外才能发送AppleEvents,但我猜杀死系统进程也是如此(如果沙箱应用程序可以做到这一点的话)。
最后,如果你觉得这很重要,你应该通过file a bug report with Apple请求一流的应用程序接口或脚本化能力。
https://stackoverflow.com/questions/5143117
复制相似问题