Почему Process.WaitForExit генерирует исключение «без процесса», даже если процесс существует? - PullRequest
11 голосов
/ 02 февраля 2012

У меня есть служба Windows, содержащая этот код:

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

Цель этого кода - выполнить извлечение IFilter для документа, мы используем отдельный процесс, потому что некоторые IFilter общеизвестно ненадежны.

Теперь этот код прекрасно работает на блоках Windows 7 и Server 2008 R2, но на Windows Server 2003 WaitForExit немедленно выдает исключение «Нет процесса, связанного с этим объектом процесса». Процесс существует и завершает свою задачу без проблем.

Кто-нибудь видел это? Кто-нибудь может пролить свет на то, почему WaitForExit откажется от этой ошибки?

Дополнительная информация

Если поместить этот код в консольное приложение и запустить его, он также отлично работает на коробке с Windws Server 2003, следовательно, может показаться, что это особая проблема при его запуске в окне службы на Windows Server 2003.

1 Ответ

15 голосов
/ 02 февраля 2012

При запуске процессов с классом System.Diagnostics.Process система может использовать функцию CreateProcess или ShellExecuteEx Win32.При использовании CreateProcess могут быть запущены только исполняемые файлы.При использовании ShellExecuteEx любой файл, который можно запустить с помощью команды «Пуск-> Выполнить» из оболочки.

Однако это совершенно разные способы запуска процессов.ShellExecuteEx включает оболочку и может, например, повторно использовать существующий экземпляр Word или Excel для открытия документа, используя информацию, хранящуюся в разделе реестра HKCR\<progid>\shell\<verb>.Это может включать, например, использование DDE для поиска и активации существующего экземпляра Excel.

См. Документацию по ShellExecuteEx SHELLEXECUTEINFO:

Обратите внимание, что ShellExecuteEx может возвращать или не возвращать hProcess в зависимости от того, был ли запущен новый процесс.Это поведение, которое вы видите.

CreateProcess - это функция более низкого уровня, которая создает процесс напрямую и просто передает эквивалентные аргументы.Он всегда возвращает дескриптор процесса.

Примечание: Поскольку вы, похоже, запускаете исполняемый файл, немного удивительно, что ShellExecuteEx не возвращает hProcess.Тем не менее, если вы хотите убедиться, что вы получили дескриптор процесса, правильное использование UseShellExecute = false.

...