7

我有一个AppleEventDescriptor需要获取发送应用程序的包标识符的地方。Apple 事件包含一个typeProcessSerialNumber可以强制转换为ProcessSerialNumber.

问题是它GetProcessPID()在 10.9 中已被弃用,并且似乎没有被认可的方式来获得pid_t可用于实例化NSRunningApplicationusing的 a -runningApplicationWithProcessIdentifier:

我发现的所有其他选项都存在于 Processes.h 中,并且也已被弃用。

我是否遗漏了什么,或者我必须忍受这个弃用警告?

4

2 回答 2

8

Brian 和 Daniel 都提供了很好的线索,帮助我找到了正确的答案,但他们建议的东西有点不对劲。这就是我最终解决问题的方法。

对于获取进程 ID 的 Apple 事件描述符而不是序列号的代码,Brian 是正确的:

// get the process id for the application that sent the current Apple Event
NSAppleEventDescriptor *appleEventDescriptor = [[NSAppleEventManager sharedAppleEventManager] currentAppleEvent];
NSAppleEventDescriptor* processSerialDescriptor = [appleEventDescriptor attributeDescriptorForKeyword:keyAddressAttr];
NSAppleEventDescriptor* pidDescriptor = [processSerialDescriptor coerceToDescriptorType:typeKernelProcessID];

问题是,如果您-int32Value从该描述符中获取值,则返回值 0(即没有进程 ID。)我不知道为什么会发生这种情况:理论上,两者pid_tSInt32都是有符号整数。

相反,您需要获取字节值(以小端序存储)并将它们转换为进程 ID:

pid_t pid = *(pid_t *)[[pidDescriptor data] bytes];

从那时起,很容易获得有关正在运行的进程的信息:

NSRunningApplication *runningApplication = [NSRunningApplication runningApplicationWithProcessIdentifier:pid];
NSString *bundleIdentifer = [runningApplication bundleIdentifier];

此外,丹尼尔的使用建议keySenderPIDAttr在很多情况下都行不通。在我们新的沙盒世界中,存储在那里的值可能是 的进程 ID /usr/libexec/lsboxd,也称为启动服务沙盒守护程序,而不是发起事件的应用程序的进程 ID。

再次感谢 Brian 和 Daniel 的帮助导致了这个解决方案!

于 2014-06-24T23:50:30.043 回答
3

您可以使用 Apple 事件描述符强制将 ProcessSerialNumber 描述符转换为 pid_t 描述符,如下所示:

NSAppleEventDescriptor* processSerialDescriptor = [myEvent attributeDescriptorForKeyword:keyAddressAttr];
NSAppleEventDescriptor* pidDescriptor = [processSerialDescriptor coerceToDescriptorType:typeKernelProcessID];
pid_t pid = [pidDescriptor int32Value];
于 2014-06-24T19:48:09.157 回答