Запуск процесса из службы - PullRequest
2 голосов
/ 25 ноября 2008

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

Основы того, что я пытаюсь сделать, таковы:

  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».

К вашему сведению, этот код я успешно использовал в другом месте, но не в службе.

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

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

Ответы [ 3 ]

2 голосов
/ 25 ноября 2008

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

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

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

0 голосов
/ 25 ноября 2008

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

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

0 голосов
/ 25 ноября 2008

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

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

...