2012-04-19 19 views
6

Sto avviando una piccola applicazione di console dall'interno della mia applicazione web IIS. Il codice viene avviato dall'interno di un pool di app utilizzando il codice come questo,Che differenza ha UseShellExecute?

Process process = new Process(); 
ProcessStartInfo processStartInfo = new ProcessStartInfo(); 

processStartInfo.CreateNoWindow = true; 
processStartInfo.WindowStyle = ProcessWindowStyle.Hidden; 

// .. 

process.Start(); 

ho usato per ottenere in modo intermittente un errore,

Win32Exception exception has occured Message: No such interface supported 
ErrorCode: 80004005 NativeErrorCode: 80004002 

ho dimostrato che quando questo è successo l'applicazione di console non partiva a tutti.

ho aggiunto al codice di sopra di questo,

processStartInfo.UseShellExecute = false; 

E il problema è andato via (finora, incrociamo le dita). Capisco che apportando questa modifica non è necessario un contesto desktop valido per l'esecuzione, ma cosa significa esattamente. Se ciò significa che non possiamo eseguire il codice sopra se non esiste un desktop (che si applica a un pool di app IIS in esecuzione con un utente di sistema), allora perché è stato utilizzato a volte in passato anziché fallire ogni volta?

Qualcuno ha idea del perché questo farebbe la differenza? Cosa significa un'interfaccia supportata in questo contesto?

UPDATE:

ho preso a bordo di tutto persone hanno detto, e fatto più ricerca me stesso. Quindi, per riassumere se hai UseShellExecute = true (che è l'impostazione predefinita) chiamerà ShellExecuteEX in shell32.dll per eseguire il processo. Lo farà questo in realtà (copiato dal System.dll utilizzando ILSpy),

public bool ShellExecuteOnSTAThread() 
{ 
    if (Thread.CurrentThread.GetApartmentState() != ApartmentState.STA) 
    { 
     ThreadStart start = new ThreadStart(this.ShellExecuteFunction); 
     Thread thread = new Thread(start); 
     thread.SetApartmentState(ApartmentState.STA); 
     thread.Start(); 
     thread.Join(); 
    } 
    else 
    { 
     this.ShellExecuteFunction(); 
    } 
    return this._succeeded; 
} 

Se hai UseShellExecute = false allora sarà chiamata CreateProcess in kernel32.dll per avviare il processo.

mi chiedevo se c'è un problema con il fatto che il codice ShellExecuteOnSTAThread sopra è la creazione di un nuovo thread? È possibile che il pool di applicazioni raggiunga un limite al threading che potrebbe causare indirettamente Win32Exception?

+0

Ho visto questa specifica modalità di errore menzionata più volte negli ultimi due mesi. Nulla di vicino a una spiegazione, ma usando UseShellExecute = false lo risolverà sicuramente. –

+0

Grazie. Dove altro l'hai visto? Non riesco davvero a trovarlo da nessuna parte? Scusa se ti faccio una domanda a cui non puoi rispondere, ma sarei curioso di trovarli. – peter

+1

Questo non risponde a ciò che Hans sta ottenendo, ma questa domanda SO ha alcuni dettagli interessanti: http://stackoverflow.com/questions/5255086/when-do-we-need-to-set-useshellexecute-to-true –

risposta

7

Questo errore può verificarsi quando alcuni oggetti COM non sono registrati, anche se è un po 'un mistero per me perché è intermittente.

In tutta onestà, però, generando un eseguibile locale da all'interno di IIS è una cosa piuttosto rara da fare e si può effettivamente causare un problema di sicurezza, o almeno causare un problema con IIS se il comando non riesce per qualche motivo e doesn' t dare il controllo al sistema.

In realtà, la procedura migliore per una cosa del genere è registrare l'azione che è necessario che si verifichi all'interno del Registro di sistema, del database o di qualche tipo di file di impostazione e fare in modo che l'applicazione locale venga eseguita come attività pianificata o come servizio di Windows.

Per riferimento, l'UseShellExec membri se sia o non il kernel dovrebbe lanciare l'exe direttamente, o se debba chiedere Explorer per avviare il file.

È possibile che si verifichi questo problema quando non è stato effettuato l'accesso a nessuno, quindi non è stata caricata una shell per avviare l'exe.

In definitiva, ciò che si sta tentando di fare è una cosa brutta in produzione: non è possibile garantire lo stato di IIS quando tenta di avviare questo exe e, giustamente, IIS non è una shell.

+0

Per qualificare il problema di sicurezza, in genere IIS viene eseguito con privilegi elevati e l'avvio di un processo nel modo in cui si sta tentando di avviarlo con lo stesso set di privilegi. IMHO questo è raramente una buona cosa. –

+1

OK, grazie. Non sono preoccupato per la sicurezza, non ho il tempo di spiegargli tutta la storia. Sono d'accordo, tu dici che potremmo avere il problema quando non c'è nessuno registrato nel server. Sembra corretto, ma non sembra essere il caso. Deve riguardare qualche altro problema causato dal "caricamento della shell". – peter

+0

Sicurezza a parte, è ancora una questione di avere uno stato valido sul server. cosa succede se qualcosa blocca l'exe e il processo di lavoro IIS si riavvia o si arresta a causa di un timeout di attività? Immagino che sapere cosa intende fare questo exe sarà di aiuto; anche se è possibile fornire solo la vista miglio-alta. –