2014-06-24 135 views
6

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

的问题是,GetProcessPID()在10.9弃用,似乎没有受到制裁的方式来获得可用于使用-runningApplicationWithProcessIdentifier:一个NSRunningApplication来实例化一个pid_t

我发现的所有其他选项都生活在Processes.h中,也被弃用。

我错过了什么,或者我必须忍受这个弃用警告吗?

回答

6

两个布赖恩和丹尼尔提供了极大的线索,帮助我找到正确的答案,但东西,他们建议只是有点关闭。以下是我最终解决问题的方法。

布赖恩是正确的有关代码以获取一个进程ID,而不是一个序列号的苹果事件描述:

// 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]; 

的问题是,如果从描述符采取0​​,一值0返回(即没有进程ID)。我不知道为什么会发生这种情况:理论上,pid_tSInt32都是有符号整数。

相反,你需要得到字节值(存储小端)扔一个进程ID:

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

从这一点来说,这是简单的,以获取有关正在运行的进程的信息:

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

此外,丹尼尔的建议使用keySenderPIDAttr将在许多情况下不起作用。在我们的新沙箱世界中,存储的值可能是/usr/libexec/lsboxd(也称为Launch Services沙箱守护程序)的进程ID,而不是发起该事件的应用程序的进程ID。

再次感谢Brian和Daniel提供的解决方案!

3

您可以使用Apple事件描述符胁迫到ProcessSerialNumber描述符转换成将为pid_t描述符,像这样:

NSAppleEventDescriptor* processSerialDescriptor = [myEvent attributeDescriptorForKeyword:keyAddressAttr]; 
NSAppleEventDescriptor* pidDescriptor = [processSerialDescriptor coerceToDescriptorType:typeKernelProcessID]; 
pid_t pid = [pidDescriptor int32Value]; 
+2

或者,您可以使用keySenderPIDAttr在没有查找发件人并强制它的情况下获取PID:[[event attributeDescriptorForKeyword:keySenderPIDAttr] int32Value] – danielpunkass