2014-06-24 11 views
6

Ho un AppleEventDescriptor in cui è necessario ottenere l'identificatore del bundle dell'applicazione di invio. L'evento Apple contiene un typeProcessSerialNumber che può essere forzato in un ProcessSerialNumber.Acquisizione di NSRunningApplication utilizzando un numero di riferimento del processo

Il problema è che GetProcessPID() è stata sconsigliata a 10,9, e là non sembra essere sanzionato modo per ottenere un pid_t che può essere utilizzato per creare un'istanza di un NSRunningApplication utilizzando -runningApplicationWithProcessIdentifier:.

Tutte le altre opzioni che ho trovato tutte vivono in Processes.h e sono anche deprecate.

Mi manca qualcosa o devo convivere con questo avviso di deprecazione?

risposta

6

Sia Brian e Daniel fornito ottimi indizi che mi ha aiutato a trovare la risposta giusta, ma la roba hanno suggerito era solo un po 'fuori. Ecco come ho finito per risolvere il problema.

Brian era corretta per il codice per ottenere un descrittore di Apple Event per un ID di processo, invece di quello per il numero di serie:

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

Il problema è che se si prende il -int32Value da quel descrittore, un viene restituito il valore 0 (ovvero nessun ID di processo). Non ho idea del perché questo accada: in teoria, sia pid_t sia SInt32 sono interi con segno.

Invece, è necessario per ottenere i valori di byte (che vengono memorizzati little endian) e gettarli in un ID di processo:

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

Da quel punto, è semplice per ottenere le informazioni relative al processo in esecuzione:

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

Inoltre, il suggerimento di Daniel di utilizzare keySenderPIDAttr non funziona in molti casi. Nel nostro nuovo mondo sandbox, il valore memorizzato è probabilmente l'id di processo per /usr/libexec/lsboxd, noto anche come il daemon della sandbox di Servizi di avvio, non l'ID di processo dell'app che ha originato l'evento.

Grazie ancora a Brian e Daniel per l'aiuto che ha portato a questa soluzione!

3

È possibile utilizzare Apple descrittore evento coercizione per tradurre il descrittore ProcessSerialNumber in un descrittore pid_t in questo modo:

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

In alternativa, è possibile utilizzare keySenderPIDAttr per ottenere il diritto al PID senza cercare il mittente e forzarlo: [[event attributeDescriptorForKeyword: keySenderPIDAttr] int32Value] – danielpunkass