2010-05-14 4 views
5

Sto cercando di rilevare quando vengono lanciate particolari applicazioni.Mac OS X: Ottenere informazioni dettagliate sul processo (in particolare i suoi argomenti di avvio) per le applicazioni in esecuzione arbitrarie che utilizzano il PID

Attualmente sto usando NSWorkspace, registrando la notifica "ha lanciato l'applicazione". Io uso anche il metodo runningApplications per ottenere app attualmente in esecuzione all'avvio della mia app.

Per la maggior parte delle app, il nome del pacchetto di app è sufficiente. Ho un plist di "app conosciute" che controllo incrociando il nome di quello passato nella notifica.

Questo funziona bene finché non si incontra un'app che funge da proxy per l'avvio di un'altra applicazione utilizzando gli argomenti della riga di comando.

Esempio: il nuovo portale sul Mac non ha un pacchetto di app dedicato. Steam può creare un collegamento, che non serve altro che avviare l'app hl2_osx con l'argomento -game e portal come parametro.

Dal momento che più giochi basati su Source si stanno dirigendo verso il Mac, immagino che useranno lo stesso metodo per lanciare, eseguendo efficacemente l'app hl2_osx con l'argomento -game.

C'è un modo carino per ottenere un elenco degli argomenti (e dei relativi parametri) utilizzando un'API Cocoa?

NSProcessInfo si avvicina, offrendo un metodo `-arguments', ma fornisce solo informazioni per il proprio processo di ...

NSRunningApplication offre la possibilità di ottenere informazioni sulle applicazioni arbitrarie utilizzando un PID, ma nessun argomenti della riga di comando ...

C'è qualcosa che colma il divario tra i due?

Sto provando a non seguire la rotta di generazione di uno NSTask per eseguire ps -p [pid] e analizzare l'output ... Preferirei qualcosa di più di alto livello.

+0

I documenti dicono che NSApplication seguirà solo "Applicazioni utente" e non altri processi. Ho bisogno di indicare nell'interfaccia utente (system-preferences) quando il mio daemon è in esecuzione/non in esecuzione, e non so come ... Posso in qualche modo ottenere queste informazioni rudimentali usando una delle API Obj-C di livello più alto? Altrimenti, puoi risparmiare uno snippet sull'analisi dell'output di ps per quello? –

risposta

7

È possibile utilizzare qualsiasi utilizzo ps, sebbene non sia basato sul cacao. Secondo Singh, ps si basa sulle chiamate kvm e sysctl. Versando il numero source, le chiamate pertinenti sembrano essere kvm_openfiles, kvm_getprocs e kvm_getargv. Per ottenere gli argomenti della riga di comando, chiamare prima lo kvm_openfiles per accedere allo spazio di memoria del kernel, quindi utilizzare kvm_getprocs per ottenere le informazioni sul processo del kernel, quindi kvm_getargv.

L'utilizzo di sysctl in ps sembra meno rilevante per il tuo obiettivo; è usato per ottenere altre informazioni, come l'ID del gruppo e l'ID del processo genitore. Il nome di sysctl specifico utilizzato è {CTL_KERN, KERN_PROC, KERN_PROC_which, flags}, dove che specifica un filtro di processo (ad es.ALL, PID) e bandiere sono argomenti per il filtro (i dettagli sono nella pagina man sysctl).

OS X non ha procfs di supporto, ma Singh ha sviluppato un FUSE based version, rilasciato sotto GPLv2. Se lo impacchettate con la vostra applicazione, dovrete rilasciarlo anche sotto GPLv2. La maggior parte di MacFUSE è rilasciata con lo BSD-style license, quindi può essere distribuita con la tua app senza renderla open source (fusefs/fuse_nodehash.c è rilasciata con la licenza open source di Apple, ma consente anche il collegamento ad app closed source).

La domanda "Get other process' argv in OS X using C" deve essere utile, in quanto ha codice di esempio che utilizza kvm e sysctl. TN 2050 "Observing Process Lifetimes Without Polling" potrebbe anche esserti utile.

+2

Le funzioni di 'kvm_' sono le" versioni di noop "a cui mi riferisco nella mia risposta. Loro non lavorano. ('sysctl' sì, ma non è un'interfaccia pubblica.) Le pagine man di' kvm_' e 'kvm.h' erano presenti in 10.4 (come vi siete collegati) ma sono passate in 10.5+. Nota che tutti i riferimenti a 'kvm' nel sorgente di' ps' sono protetti da '#ifndef __APPLE__' o' #if FIXME' - la mia ipotesi è che gli sviluppatori pianificano di implementare 'kvm_ *' in futuro ma non hanno avuto tempo (e forse mai). –

3

No: l'esecuzione di ps è la soluzione migliore. Le interfacce di informazioni di processo standard non sono supportate su OS X (le versioni di noop erano fornite in OS X 10.4, ma successivamente rimosse) e le interfacce private sono suscettibili di cambiare tra le revisioni di OS X.

Se sei disposto a bloccarti in una singola versione di OS X, tutta la sorgente è disponibile, ad esempio per ps o libproc; dovrai anche eseguire come root.

Problemi correlati