2010-11-04 15 views
8

In Windows, c'è un modo per avviare un processo in C++ e poi leggere ciò che sputa in stdout quando è finito? Il processo deve essere eseguito utilizzando privilegi elevati (su Vista o successivi) se necessario.Leggi lo stdout di un altro processo in C++

Attualmente sto utilizzando ShellExecuteEx() per avviare il processo ed eseguire un ciclo while finché GetExitCodeProcess() non restituisce più STILL_ACTIVE tramite il parametro lpExitCode (con una chiamata WaitForSingleObject() che esegue un attesa di 100 msec durante ogni iterazione) .

+0

È possibile reindirizzare lo stdout in una named pipe quando si avvia il processo? (Non è uno sviluppatore C++, quindi questo è un commento) –

+3

Il problema è che per eseguire un processo elevato è necessario usare 'ShellExecuteEx()' con il verbo 'runas'. E 'ShellExecuteEx()' non supporta il reindirizzamento dell'output AFAICT. –

risposta

3

Non c'è un modo semplice per farlo.

Calling ShellExecuteEx() con la runas verbo invia un messaggio RPC al strega AppInfo servizio NT quindi eseguire l'applicazione da una sessione elevata. Non ci sono API per collegare facilmente l'input/output del processo elevato alla tua applicazione.

Thomas Hruska nel suo The Code Project article presenta la sua implementazione di una funzione CreateProcessElevated() che risolve questo problema.

invece di eseguire il programma di elevata direttamente CreateProcessElevated() si basa su un altro eseguibile che ricevono il nome dei stdin, stdout, stderr named pipe e ricreare le loro maniglie nella sessione elevata prima di chiamare CreateProcess().

+0

Mi piace la soluzione Code Project. Sfortunatamente, poiché coinvolge una DLL separata, non potrò usarla per il mio particolare progetto, che è un'applicazione di bootstrap di un installatore. (Sigh! Torna al tavolo da disegno, credo.) – RobH

0

È necessario creare una pipe denominata per il processo figlio. This MSDN article spiega con e ha esempi di codice.

Si dovrebbe essere in grado di farlo andare da quello.

+0

Sfortunatamente, questa soluzione utilizza CreateProcess() anziché ShellExecuteEx(). –

1

È necessario sostituire l'uso di ShellExecuteEx con CreateProcess. L'argomento lpStartupInfo consente agli handle std in e std out del processo. Basta creare una pipe anonima usando CreatePipe che si passa come argomenti. Questo MSDN article ha un esempio di come farlo.

+0

Ma CreateProcess() non può essere utilizzato per avviare un processo con privilegi elevati, a meno che anche il processo padre non sia elevato. –

0

Non è possibile utilizzare CreateProcess/ShellExecuteEx per eseguire una shell cmd con stdout/stderr reindirizzato che a sua volta richiama il processo?

"cmd/c YourProcess.exe {parametri}" ecc.?

Problemi correlati