2008-11-25 2 views
2

Я пытаюсь запустить другой процесс из службы (это консольное приложение, которое собирает некоторые данные и записывает их в реестр), но по какой-то причине я не могу запустить его правильно.Запуск процесса из службы

основы I того, что я пытаюсь сделать это следующим образом:

  1. запустить процесс
  2. Дождитесь завершения процесса
  3. Получить код возврата из процесса

в настоящее время я использую следующий код:

STARTUPINFO info={sizeof(info)}; 
PROCESS_INFORMATION processInfo; 
if (CreateProcess(PATH, ARGS, NULL, NULL, TRUE, 0, NULL, NULL, &info, &processInfo)) 
{ 
    ::WaitForSingleObject(processInfo.hProcess, INFINITE); 

    DWORD exit = 100; 
    GetExitCodeProcess(processInfo.hProcess, &exit); 

    CloseHandle(processInfo.hProcess); 
    CloseHandle(processInfo.hThread); 

    return exit; 
} 

При вызове CreateProcess() он преуспевает и вводит тело оператора if. Вызов WaitForSingleObject немедленно возвращается, чего не следует, так как процесс должен занять примерно 20-30 секунд. И, наконец, вызов GetExitCodeProcess() завершается с ошибкой и не устанавливает значение «exit».

FYI, это код, который я действительно использовал в других местах с успехом, просто не в службе.

Может ли быть запущено из службы и есть проблемы с разрешениями?

Редактировать: Теперь я понял, что он действительно запустит приложение (я вижу его в TaskMan), но он кажется застрявшим. Он там, но ничего не делает.
Основываясь на suggestion Роба Кеннеди, я исправил проблему с дескриптором процесса, и он действительно ждет завершения процесса. Но он никогда не заканчивается, если я не убью его вручную.

ответ

2

WaitForSingleObject и GetExitCodeProcess ожидают самого дескриптора процесса, а не указателя на дескриптор процесса. Удалите амперсанды.

Кроме того, проверьте возвращаемые значения и позвоните по телефону GetLastError, когда они не работают. Это поможет вам диагностировать будущие проблемы. Никогда не предполагайте, что функция API всегда будет успешной.

Как только вы вызываете функции правильно, и новый процесс начинается, но не делает успехов, вы можете быть уверены, что этот код не является преступником. Проблема заключается в новом процессе, поэтому сосредоточьте свои задачи отладки там, а не на процессе обслуживания.

0

После обновления и редактирования это звучит как одна из многих возможных ошибок при запуске процесса из службы. Есть ли какая-либо возможность - какой бы то ни было - что ваш внешний процесс ждет взаимодействия с пользователем? Есть три основных примера, которые я могу придумать, например, приложение командной строки, которое в некоторых случаях может потребовать ввода с клавиатуры (например, что-то вроде «cmd/c del *. *» Потребует подтверждения пользователя). Другие примеры будут применены, если приложению понадобится окно и отображает его, но вы не можете его увидеть. Если это так, вы можете настроить свою службу на «взаимодействие с рабочим столом» во время отладки, а затем сможете увидеть либо окно приложения (или непредвиденное сообщение об ошибке Windows, например, неспособное найти DLL или подобное).

Если это поможет вам отлаживать или нет, обычно это «а-ха!». момент приходит от осознания того, что такие вещи, как переменные среды, путь, текущий каталог и т. д., не являются тем, чего вы ожидаете от службы. Разрешения не являются наиболее распространенной причиной такого рода проблем.Не могли бы вы предоставить некоторые сведения о внешнем приложении, которое вы пытаетесь запустить, возможно, это поможет в этом.

0

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

Если вы можете, попробуйте изменить процесс в полный исполняемый файл Windows, но пропустите часть, в которой вы пытаетесь создать окно.

Смежные вопросы