2012-02-02 9 views
8

Mam usługa Windows zawierający ten kod:Dlaczego metoda Process.WaitForExit zgłasza wyjątek "brak procesu", nawet jeśli proces istnieje?

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()); 
      } 
     } 
    } 

Celem niniejszego kod jest uruchamiany wyciąg IFilter na dokumencie używamy proces oddzielna ponieważ niektóre IFilters są notorycznie łuszcząca.

Teraz ten kod działa idealnie dobrze w systemach Windows 7 i Server 2008 R2, ale w systemie Windows Server 2003 WaitForExit natychmiast wyrzuca wyjątek "Nie ma procesu związanego z tym obiektem procesu". Proces istnieje i wykonuje swoje zadanie bez problemu.

Ktoś to widział? Czy ktokolwiek może rzucić jakiekolwiek światło na to, dlaczego WaitForExit może spowodować ten błąd?

Dodatkowe informacje

Gdybym umieścić ten kod w app konsoli i uruchomić to działa dobrze na Server 2003 polu Windws jak również, dlatego wydaje się, że jest to konkretny problem z uruchomieniem tego w usłudze na w systemie Windows Server 2003.

+0

Bardzo trudno to wyjaśnić za pomocą tego kodu. Tinker z ustawieniami usługi. Upewnij się, że opcja "interakcja z komputerem" jest wyłączona. Opublikuj wszystko, co znajdziesz w dzienniku zdarzeń aplikacji. –

+1

Błąd pojawia się, gdy nie dostaniesz UCHWYTU do procesu (stąd nie możesz na niego czekać). Upewnij się, że określasz UseShellExecute = false, aby zapobiec ponownemu użyciu procesu. Czy możesz opisać bitness 32 vs 64 usługi w stosunku do pliku wykonywalnego? Na koniec spróbuj Process Monitor i zobacz, co się dzieje. – Ben

+0

@Hans: Nic nie pojawia się w żadnym z dzienników zdarzeń (przynajmniej nic, że mój kod celowo nie umieszcza).Nie jestem pewien, gdzie znaleźć opcję "interakcji z pulpitem" "? – AnthonyWJones

Odpowiedz

13

Podczas uruchamiania z klasą System.Diagnostics.Process system może korzystać z funkcji Win32: CreateProcess lub ShellExecuteEx. Podczas korzystania z CreateProcess można uruchamiać tylko pliki wykonywalne. Podczas korzystania z ShellExecuteEx, każdy plik, który można uruchomić za pomocą polecenia "Start-> Uruchom" z powłoki.

Są to jednak zupełnie różne sposoby uruchamiania procesów. ShellExecuteEx obejmuje powłokę i może, na przykład, ponownie użyć istniejącego wystąpienia programu Word lub Excel w celu otwarcia dokumentu, korzystając z informacji przechowywanych pod kluczem rejestru HKCR\<progid>\shell\<verb>. Może to obejmować na przykład użycie DDE w celu wyszukania, a następnie aktywowania istniejącej instancji programu Excel.

Patrz dokumentacja ShellExecuteEx „s SHELLEXECUTEINFO:

Zauważ, że ShellExecuteEx może lub nie może zwrócić hProcess w zależności od tego, czy nowy proces został rozpoczęty. To jest zachowanie, które widzisz.

CreateProcess jest funkcją niższego poziomu i tworzy proces bezpośrednio, i po prostu przekazuje równoważne argumenty. Zawsze zwraca uchwyt procesu.

Uwaga: Ponieważ wydaje się być rozpoczęcie plik wykonywalny, to jest trochę dziwne, że nie hProcess jest zwracany przez ShellExecuteEx. Niemniej jednak, jeśli chcesz upewnić się, że uzyskasz uchwyt procesu, poprawne jest użycie UseShellExecute = false.