2014-06-24 18 views
6

Mam AppleEventDescriptor, gdzie muszę uzyskać identyfikator pakunku aplikacji wysyłającej. Wydarzenie Apple zawiera plik typeProcessSerialNumber, który można przekształcić w ProcessSerialNumber.Uzyskiwanie NSRunningApplication za pomocą ProcessSerialNumber

Problemem jest to, że GetProcessPID() została zaniechana w 10,9, a tam nie wydaje się być usankcjonowany sposób, aby uzyskać pid_t które mogą być używane do instancji NSRunningApplication użyciu -runningApplicationWithProcessIdentifier:.

Wszystkie inne opcje, które znalazłem, są dostępne w Processes.h i są również przestarzałe.

Czy czegoś brakuje lub czy muszę żyć z ostrzeżeniem o odstąpieniu od umowy?

Odpowiedz

6

Zarówno Brian i Daniel warunkiem wspaniałych wskazówek, które pomogły mi znaleźć właściwą odpowiedź, ale rzeczy zasugerowali było tylko trochę. Oto, jak doszło do rozwiązania problemu.

Brian był prawidłowy o kodzie uzyskać deskryptor jabłko wydarzenie dla identyfikatora procesu zamiast jednego numeru seryjnego:

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

Problemem jest to, że jeśli wziąć -int32Value z tego deskryptora, A zwracana jest wartość 0 (tzn. brak identyfikatora procesu). Nie mam pojęcia, dlaczego tak się dzieje: teoretycznie zarówno pid_t, jak i SInt32 są liczbami całkowitymi ze znakiem.

Zamiast tego, trzeba uzyskać wartości bajtów (które są przechowywane little endian) i rzucać je na identyfikator procesu:

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

od tego punktu, to proste, aby uzyskać informacje na temat uruchomionego procesu:

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

również sugestia Daniela korzystania keySenderPIDAttr nie będzie działać w wielu przypadkach. W naszym nowym świecie piaskownicy wartość tam zapisana prawdopodobnie będzie identyfikatorem procesu dla /usr/libexec/lsboxd, nazywanym także demonem usługi uruchamiania usługi Sandbox, a nie identyfikatorem procesu aplikacji, która spowodowała wydarzenie.

Jeszcze raz dziękuję Brianowi i Danielowi za pomoc, która doprowadziła do tego rozwiązania!

3

Można użyć firmy Apple deskryptora zdarzenia przymus tłumaczyć deskryptor ProcessSerialNumber w deskryptorze pid_t tak:

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

Alternatywnie można użyć keySenderPIDAttr, aby uzyskać prawo w PID bez wyszukiwania nadawcy i wymuszania go: [[event attributeDescriptorForKeyword: keySenderPIDAttr] int32Value] – danielpunkass

Powiązane problemy