2012-02-02 4 views
8

Ho un servizio di Windows che contiene questo codice:Perché Process.WaitForExit genera un'eccezione "nessun processo" anche quando esiste un processo?

public static void ExtractTextInner(string source, string destination) 
    { 
     ProcessStartInfo startInfo = new ProcessStartInfo(); 
     startInfo.FileName = EXTRACTOR_EXE_FILEPATH 
     startInfo.Arguments = "\"" + source + "\" \"" + destination + "\""; 
     startInfo.CreateNoWindow = true; 
     startInfo.WindowStyle = ProcessWindowStyle.Hidden; 

     Process process = new Process(); 
     process.StartInfo = startInfo; 

     process.Start(); 
     process.WaitForExit(); 
     int exitCode = process.ExitCode; 
     process.Close(); 
     if (exitCode != 0) 
     { 
      switch (exitCode) 
      { 
       case 1: 
       throw new ApplicationException("IFilter Extraction Failed"); 
       default: 
       throw new ApplicationException("Unknown Exit Code:" + exitCode.ToString()); 
      } 
     } 
    } 

Lo scopo di questo codice viene eseguito un estratto IFilter su un documento, si usa un processo separato perché alcuni IFilters sono notoriamente traballante.

Ora questo codice funziona perfettamente su Windows 7 e Server 2008 R2 ma su Windows Server 2003 lo WaitForExit genera immediatamente un'eccezione "Nessun processo associato all'oggetto Processo". Il processo esiste e completa il suo compito senza problemi.

Chiunque ha visto questo? Qualcuno può far luce sul motivo per cui WaitForExit avrebbe generato questo errore?

Altre Informazioni

Se metto questo codice in una console app e corro funziona bene sulla scatola Windws Server 2003 e, quindi, sembrerebbe essere un problema specifico al funzionamento di questo in un servizio su una scatola di Windows Server 2003.

+0

Questo è molto difficile da spiegare con questo codice. Tinker con le impostazioni del servizio. Assicurati che l'opzione "interagisci con il desktop" sia disattivata. Pubblica tutto ciò che trovi nel registro eventi dell'applicazione. –

+1

L'errore si verifica quando non si ottiene una MANIGLIA per il processo (quindi non può attendere per questo). Assicurati di specificare UseShellExecute = false, per impedire il riutilizzo di un processo. Puoi anche descrivere il testimone 32 vs 64 del servizio rispetto all'eseguibile? Infine prova Process Monitor e guarda cosa sta succedendo. – Ben

+0

@Hans: non appare nulla dei registri eventi (almeno nulla che il mio codice non stia deliberatamente inserendo lì).Non sono sicuro di dove trovare l'opzione "interagire con il desktop" " – AnthonyWJones

risposta

13

All'avvio dei processi, con la classe System.Diagnostics.Process, il sistema può utilizzare la funzione Win32. Quando si utilizza CreateProcess, è possibile avviare solo i file eseguibili. Quando si utilizza ShellExecuteEx, qualsiasi file che può essere avviato utilizzando il comando "Start-> Esegui" dalla shell.

Tuttavia, questi sono modi completamente diversi di avviare i processi. ShellExecuteEx coinvolge la shell e può, ad esempio, riutilizzare un'istanza esistente di Word o Excel per aprire un documento, utilizzando le informazioni memorizzate nella chiave di registro HKCR\<progid>\shell\<verb>. Ciò potrebbe comportare, ad esempio, l'utilizzo di DDE per cercare e quindi attivare un'istanza di Excel esistente.

vedere la documentazione sul ShellExecuteEx s' SHELLEXECUTEINFO:

noti che ShellExecuteEx può o non può restituire un hProcess a seconda se è stato avviato un nuovo processo. Questo è il comportamento che stai vedendo.

CreateProcess è una funzione di livello inferiore e crea direttamente un processo e passa semplicemente gli argomenti equivalenti. Restituisce sempre un handle di processo.

Nota: Dal momento che ti sembra di essere a partire da un file eseguibile, è un po 'sorprendente che nessun hProcess viene restituito da ShellExecuteEx. Tuttavia, se vuoi assicurarti di ottenere un handle di processo, usare UseShellExecute = false è la cosa giusta da fare.

Problemi correlati