2014-06-24 122 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