使用ProcessSerialNumber获取NSRunningApplication

时间:2014-06-24 19:31:44

标签: objective-c applescript nsrunningapplication

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

问题是{10}中已弃用GetProcessPID(),并且似乎没有获得批准的方法来获取pid_t,可以使用NSRunningApplication-runningApplicationWithProcessIdentifier:使用{{ 1}}。

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

我是否遗漏了某些内容,或者我是否必须接受此弃用警告?

2 个答案:

答案 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_tSInt32是有符号整数。

相反,您需要获取字节值(以小端存储)并将它们转换为进程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];