8

我正在尝试检测特定应用程序何时启动。

目前我正在使用NSWorkspace,注册“启动应用程序”通知。我还使用该runningApplications方法来获取我的应用程序启动时当前正在运行的应用程序。

对于大多数应用程序,应用程序包的名称就足够了。我有一个“已知应用程序”列表,我会与通知中传递的名称进行交叉检查。

这工作正常,直到您遇到一个应用程序,该应用程序充当使用命令行参数启动另一个应用程序的代理。

示例:Mac 上新发布的 Portal 没有专门的应用程序包。Steam 可以创建一个快捷方式,它的作用只不过是hl2_osx使用参数启动应用程序-gameportal作为它的参数。

由于更多基于 Source 的游戏正在走向 Mac,我想他们将使用相同的方法来启动,有效地运行hl2_osx带有-game参数的应用程序。

有没有一种使用 Cocoa API 获取参数(及其参数)列表的好方法?

NSProcessInfo接近了,提供了一个“-arguments”方法,但只提供了它自己的过程的信息......

NSRunningApplication提供使用 PID 获取有关任意应用程序信息的能力,但没有命令行参数...

有什么可以填补两者之间的空白吗?

我试图不走产生NSTask运行ps -p [pid]和解析输出的路线......我更喜欢更高级别的东西。

4

2 回答 2

12

你可以使用任何ps用途,尽管它不是基于可可的。根据Singh的说法,ps它基于 kvm 和 sysctl 调用。源源不断地涌来,相关的呼声似乎是kvm_openfileskvm_getprocskvm_getargv。要获取命令行参数,首先调用kvm_openfiles获取内核内存空间的访问权限,然后使用kvm_getprocs获取内核进程信息,然后使用kvm_getargv.

sysctlin的使用ps似乎与您的目标不太相关;它用于获取其他信息,例如组 ID 和父进程 ID。使用的特定 sysctl 名称是,其中指定进程过滤器(例如,),标志是过滤器的参数(详细信息在手册页中)。{CTL_KERN, KERN_PROC, KERN_PROC_which, flags}ALLPIDsysctl

OS X 不支持 procfs,但 Singh 开发了基于 FUSE 的版本,在 GPLv2 下发布。如果您将它与您的应用程序捆绑在一起,您也必须在 GPLv2 下发布它。大多数 MacFUSE 是在BSD 风格的许可证下发布的,因此它可以与您的应用程序一起分发而无需使其开源(fusefs/fuse_nodehash.c 是在 Apple 的开源许可证下发布的,但它也允许链接到闭源应用程序)。

Get other process' argv in OS X using C ”这个问题应该很有用,因为它有使用 kvm 和 sysctl 的示例代码。TN 2050“在没有轮询的情况下观察过程生命周期”也可能对您有用。

于 2010-05-14T23:51:01.230 回答
4

不——跑步ps是你最好的选择。OS X 不支持标准进程信息接口(在 OS X 10.4 中提供了 noop 版本,但此后被删除)并且私有接口可能会在 OS X 版本之间发生变化。

如果您愿意将自己锁定在单个 OS X 版本中,则所有源代码都可用,例如pslibproc;您还需要以 root 身份运行。

于 2010-05-14T23:42:45.840 回答