我有AppleEventDescriptor
我需要获取发送应用程序的包标识符。 Apple事件包含typeProcessSerialNumber
,可以强制转换为ProcessSerialNumber
。
问题是{10}中已弃用GetProcessPID()
,并且似乎没有获得批准的方法来获取pid_t
,可以使用NSRunningApplication
来-runningApplicationWithProcessIdentifier:
使用{{ 1}}。
我发现的所有其他选项都存在于Processes.h中,并且也已弃用。
我是否遗漏了某些内容,或者我是否必须接受此弃用警告?
答案 0 :(得分:7)
Brian和Daniel都提供了很好的线索,帮助我找到了正确的答案,但他们建议的东西只是有点偏。以下是我最终解决问题的方法。
Brian对于获取进程ID的Apple事件描述符而不是序列号的代码的代码是正确的:
// 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_t
和SInt32
是有符号整数。
相反,您需要获取字节值(以小端存储)并将它们转换为进程ID:
pid_t pid = *(pid_t *)[[pidDescriptor data] bytes];
从那时起,可以直接获得有关正在运行的进程的信息:
NSRunningApplication *runningApplication = [NSRunningApplication runningApplicationWithProcessIdentifier:pid];
NSString *bundleIdentifer = [runningApplication bundleIdentifier];
此外,Daniel的使用keySenderPIDAttr
的建议在许多情况下都不起作用。在我们新的沙盒世界中,存储在那里的值很可能是/usr/libexec/lsboxd
的进程ID,也称为启动服务沙箱守护程序,而不是发起事件的应用程序的进程ID。
再次感谢Brian和Daniel提供的解决方案的帮助!
答案 1 :(得分:3)
您可以使用Apple事件描述符强制将ProcessSerialNumber描述符转换为pid_t描述符,如下所示:
NSAppleEventDescriptor* processSerialDescriptor = [myEvent attributeDescriptorForKeyword:keyAddressAttr];
NSAppleEventDescriptor* pidDescriptor = [processSerialDescriptor coerceToDescriptorType:typeKernelProcessID];
pid_t pid = [pidDescriptor int32Value];