2009-04-07 12 views
5

Ho un'applicazione in esecuzione come utente normale e un servizio in esecuzione come sistema locale. Voglio che l'applicazione sia in grado di dire al servizio di riavviare l'applicazione, una volta che il servizio ha fatto altre cose. (Quindi l'applicazione non verrà eseguita mentre il servizio sta facendo la sua "cosa".) Affinché il servizio sia in grado di avviare l'applicazione come utente che l'ha avviata per la prima volta, ha bisogno di un token utente. L'applicazione invia il token al servizio prima che si chiuda, ma il token/handle non è valido quando il servizio sta tentando di usarlo. (La prima cosa che fa è DuplicateTokenEx per ottenere un token primario.)Come ottengo un token utente valido per CreateProcessAsUser?

Un token utente è sempre valido solo nel processo che ha chiamato OpenProcessToken?

C'è qualche altro modo in cui questo potrebbe essere fatto? Non voglio che l'utente debba "accedere" all'applicazione con logonuser. Sarebbe semplicemente sciocco. Immagino di poter passare un handle di processo per "explorer.exe" dall'app al servizio, che il servizio potrebbe utilizzare per ottenere un token utente, ma che richiederebbe l'accesso a PROCED DUP HANDLE. Non sono entusiasta di questa soluzione, ma forse è il modo di farlo?

risposta

2
+0

Grazie, vado con il primo articolo, creando un token con ZwCreateToken. È un po 'complicato imballare tutte le cose di cui ho bisogno in un messaggio, ma a quanto pare ha funzionato per gli altri .. –

+0

Il primo articolo sembra avere alcuni errori, il secondo sembra abbastanza buono.Ma non sono sicuro del perché dovresti usare ZwCreateToken (un metodo non documentato, non supportato e non del tutto stabile) quando ci sono metodi documentati per fare ciò che vuoi. –

+0

Scusa, volevo dire secondo. Non riuscivo nemmeno a trovare il primo. Sto facendo qualcosa come http://www.apnilife.com/E-Books_apnilife/Windows%20Programming_apnilife/Windows%20NT%20Undocumented%20APIs/1996%20Ch08_apnilife.pdf. Ti riferisci a CreateToken? –

3

Si dispone di più problemi qui quindi cercherò di affrontare separatamente e mi posso correggere se ho capito male:

  1. Sembra che tu abbia un servizio e un'applicazione utente che non può eseguire determinate funzionalità allo stesso tempo. Per ottenere ciò, il servizio interrompe l'applicazione, esegue la funzionalità speciale, quindi riavvia l'applicazione. Se questo è corretto, a mio parere, hai un difetto di progettazione. Anziché arrestare, quindi riavviare l'applicazione, è necessario coordinare l'accesso alla risorsa condivisa mediante l'esclusione reciproca utilizzando un mutex denominato e/o utilizzando un metodo IPC come pipe denominate per comunicare le intenzioni.

  2. Un token utente è sempre valido solo nel processo che ha chiamato OpenProcessToken? Sì, l'handle di token che hai ricevuto è un indice nella tabella degli handle del processo, non è direttamente trasferibile. Dovresti usare DuplicateHandle che potrebbe essere quello che vuoi ma potrebbe essere disordinato.

  3. Si desidera trovare il modo migliore per ottenere il token dell'utente per avviare l'applicazione nella sessione (interattiva?) Dell'utente. In tal caso, il modo migliore è recuperare il token di sessione dell'utente e usarlo. Puoi controllare this article e il codice di esempio, è in C#, ma dovrebbe essere relativamente facile da trasferire alla tua lingua preferita.

EDIT: aggiornato per includere Windows 2000. Dal momento che si sta eseguendo il servizio sotto il sistema di account può aprire un handle per il processo stesso (se necessario il processo può inviare il suo ID di processo). Può quindi aprire il token collegato a quel processo, duplicarlo e utilizzare il token risultante per avviare (o rilanciare) l'applicazione di destinazione.

+0

1. Potrebbe sembrare un difetto di progettazione. Il fatto è che il servizio potrebbe voler aggiornare l'applicazione: potrebbe non essere nemmeno la stessa applicazione che dovrebbe essere lanciata. 2. D'accordo, lo è. Proverò a creare un nuovo token. 3. Deve funzionare nel 2000, dimenticato di menzionare che ... –

+0

Perché il servizio non chiama semplicemente OpenProcessToken e DuplicateTokenEx stesso piuttosto che avere il processo inviare qualcosa al servizio? –

+0

Non sarebbe il processo creato essere eseguito come sistema locale in quel caso? Se lo faccio potrei anche chiamare CreateProcess e non preoccuparmi affatto dei token utente. –