打电话给另一个程序的功能?

时间:2009-05-14 22:04:47

标签: cocoa macos scripting

所以我有这个我非常喜欢的程序,它不支持Applescript。我想稍微自动化一下。现在,我知道我可以使用applescript告诉程序告诉菜单告诉子菜单告诉菜单项激活或者其他什么,但坦率地说我不太喜欢Applecript。

当我在IB中打开NIB文件时,我可以看到正在发送给FirstResponder的消息;例如,“复制”菜单项发送“copy:”。有没有办法让我直接从另一个程序调用它?

3 个答案:

答案 0 :(得分:2)

没有。你知道,它被称为受保护的内存是有原因的。另一个程序与您的应用程序完全隔离。有一些方法可以将代码放入其他应用程序,但(a)它是非常不可取的(b)需要root权限,这意味着你的应用程序的其余部分需要坚如磐石和不可思议,并且(c)编写这样的代码是一种黑色的艺术需要了解操作系统内核接口,虚拟内存管理,ABI,链接器/加载程序的内部,汇编程序编程,以及运行应用程序的特定处理器的操作参数和其他细节。

实际上,AppleEvents和其他此类IPC机制是有原因的。

你的其他选择(所有这些都是有点hacky,说实话,并给你一个相当重要的负担,确保目标应用程序处于你想要/期望的状态)访问你正在寻找的数据是:

  1. 来自ApplicationServices框架的Accessibility API,您可以通过它遍历UI树以直接从任何位置获取文本,或者可以激活菜单项。但是,用户必须明确授予您的应用访问权限(尽管这与UI脚本的要求非常相似)。
  2. 您可以使用CoreGraphics API(再次在ApplicationServices框架内)将键盘事件直接发送到目标应用程序(或仅发送到系统)。这意味着发送四个事件:Command-down,C-down,C-up,Command-up。
  3. 这些都不是理想的。说实话,您最好的方法是查看您的要求,并找出如何通过以某种方式更改这些要求来最好地解决问题,即不要直接抓取某些内容,要求用户提供一些输入等。

答案 1 :(得分:1)

您可能对SIMBLmach_inject感兴趣。 SIMBL是一个守护进程(在我的基于mach_inject的fork中,在基于通过一些ScriptingAdditions hack注入的原始版本中)为您执行注入,因此您只需要将包含代码的包放入SIMBL目录中并且SIMBL将注入它为你进入目标应用程序。或者您可以通过mach_inject自己完成。或者更方便的是,mach_inject_framework注入并运行只加载一些框架的代码。

答案 2 :(得分:0)

我认为吉姆可能会夸大这一点;他没错,但似乎有误导性。有很多方法可以让Cocoa程序在你的控制下执行自己的代码(Carbon更难)。 Accessibility API通常以这种方式使用(通常我希望它最终会被重新利用)。 Fscript可以为您提供对另一个Cocoa程序内部的各种访问。虽然输入管理器可能会在某个时候退出现场,但SIMBL仍然在那里做这种事情。

无论您是否喜欢Applescript,Apple Events都是Apple提供程序间控制的主要方式。您是否仔细检查了脚本编辑器的开放库函数,以确定该程序是否确实有任何Applescript支持?您现在可以使用Leopard的Scripting Bridge完全在Objective-C中编写Apple Events。如果你愿意的话,我写了一个tutorial(它仍然没有被Apple记录)。

可可是逆向工程师的梦想。主持SIMBL的同一个人有一个很好的intro to the subject"Wolf"也写了很多有用的信息。

吉姆是对的。如果做得不正确(有时即使正确完成),其中许多方法都可能完全破坏系统的稳定性。我在生产系统上没有做太多这样的事情;我需要他们工作。但是有很多东西你可以让Mac应用程序做,而且它是Mac开发人员培训的一个很好的部分,可以理解所有部分的真正工作。