запуск программы из службы - PullRequest
2 голосов
/ 27 июля 2011

Я работаю над службой Windows, написанной на C ++ с использованием vs2005, и столкнулся с проблемой.

Служба должна запустить другой небольшой исполняемый файл и получить его вывод.Я делаю это через вызов CreateProcess (ну, на самом деле, библиотека делает это для меня (libexecstream)), он работает.

Запускаемый исполняемый файл находится где-то на диске, я не знаю, где, иего каталог находится в переменной окружения path.Мой сервис просто запускает "theTool.exe" и мы идем.
Если переменная пути выглядит так: smting;smthingelse;C:\Program Files\blah\bin;meow она работает.
Но если путь выглядит так: smting;smthingelse;%ProgramFiles%\blah\bin;meow больше не работает!

Проблема в том, что на некоторых машинах он выглядит как первый, на других - как второй ...
Самое смешное, что если я запускаю его в консоли (а не как сервис)все работает отлично!

Есть ли способ избежать этой проблемы?программно?Такое решение, как изменение его руками, не является вариантом (клиент не хочет его).Изменение его в скрипте установки или что-то подобное также не вариант, потому что впоследствии может быть изменен путь.
И изменение инструмента тоже не вариант, потому что мы этого не делали, и у нас нет источникакод.

edit: строка CreateProcess выглядит следующим образом:

STARTUPINFO si;
ZeroMemory( &si, sizeof( si ) );
si.cb=sizeof( si );
si.hStdError = err.w();
si.hStdOutput = out.w();
si.hStdInput = in.r();
si.dwFlags |= STARTF_USESTDHANDLES;
PROCESS_INFORMATION pi;
ZeroMemory( &pi, sizeof( pi ) );
if( !CreateProcess( 0, const_cast< char * >( command.c_str() ), 0, 0, TRUE, 0, 0, 0, &si, &pi ) ) {
throw os_error_t( "exec_stream_t::start: CreateProcess failed.\n command line was: "+command );
}

где command - это "theTool"

2ndedit : если моя программа запускается как служба, она не работает, если она запускается в консоли, она работает

Ответы [ 3 ]

3 голосов
/ 27 июля 2011

Проблемы переменных среды могут быть сложными, особенно когда вы говорите об услугах. Несколько мыслей:

  1. Используйте Process Explorer , чтобы проверить, под каким пользователем запущен процесс. Убедитесь, что пользователь, под которым запущена служба, имеет соответствующую настройку vars среды (хотя это не должно быть проблемой, если у вас такой же ванильный как% programfiles%)

  2. Если вы каким-то образом программно меняете переменную среды, существуют известные проблемы с кэшированием переменных среды при запуске .

Просто некоторые мысли.

2 голосов
/ 27 июля 2011

%ProgramFiles% - это еще одна переменная среды в вашей записи значения переменной среды.Вы должны решить это.Если при анализе пути вы сталкиваетесь с этим шаблоном, то вам нужно найти его и использовать UNC-путь всех частей, чтобы указать на ваш файл.

Пара способов обшивки кошки здесь:

  • Используйте GetEnvironmentStrings Windows API, чтобы получить все заранее и поместить их в карту для удобного поиска вашим сервисом
  • Используйте GetEnviromentVariable, чтобы проверить существование и получить значение определенной переменной среды дляпример ProgramFiles
  • Запрос реестра для переменных среды в HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment
  • Установите собственную переменную среды вместо использования PATH, который должен быть зарезервирован для системных вещей и не обманываться с помощьюв любом случае
  • Используйте более надежную библиотеку файловой системы, которая имеет функции для работы с переменными среды
  • Забудьте переменные среды и используйте файл конфигурации (это может сопровождаться простой программой с графическим интерфейсом, которая позволяет им использоватьдиалог открытия файла для просмотра и выбора путей, которые будут сохранены для вашего сервиса, ииспользуйте позже)
  • и т. д.
0 голосов
/ 27 июля 2011

Вместо использования CreateProcess вместо можно использовать App Paths ключ реестра и запустить приложение с ShellExecute.Это позволяет избежать загрязнения переменной окружения PATH.

...