Запуск внешней программы (pscp) из службы Windows не работает

Я пишу службу Windows на C ++ (Visual Studio 2010), и эта служба должна отправлять файл на удаленный сервер через безопасную копию (для этого я использую pscp.exe).

Итак, я использую функцию system для запуска pscp.exe, и при запуске в качестве обычного приложения все работает нормально.

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

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

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

Любые идеи?

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

Спасибо!

- Аугусто Каринги


person Augusto Caringi    schedule 06.12.2010    source источник
comment
Какую учетную запись вы пытаетесь использовать? Большинство служб работают как локальная система. Очевидно, этого недостаточно для pscp, если он должен подключаться к удаленному хосту.   -  person MSalters    schedule 10.12.2010


Ответы (4)


Каковы ваши варианты pscp вызова? Если есть опция «без звука», используйте ее, чтобы избежать взаимодействия с консолью. Часто это -q или /q.

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

person Steve Townsend    schedule 06.12.2010
comment
Сервис может без проблем записать файл в указанный каталог. И я думаю, что если программа pscp запускается с той же учетной записью пользователя, она также может читать файл. - person Augusto Caringi; 06.12.2010

Вы можете попробовать использовать олицетворение. Что-то вроде этого...

    wchar_t* cmPath=readRegistryString(L"Software\\" TO_WCHAR(ORG_NAME) L"\\" TO_WCHAR(APP_NAME) L"\\" TO_WCHAR(APPLICATION_GROUP),TO_WCHAR(APPLICATION_EXEC_PATH));
if (!cmPath)
{
    return false;
}
HANDLE userToken=NULL;
DWORD sessId=WTSGetActiveConsoleSessionId ();
if((long)sessId==-1)
{
    sessId=0;
}
WTSQueryUserToken (sessId, &userToken);
bool result=false;
if(userToken/**/ )
{
    SECURITY_ATTRIBUTES sa;
    ZeroMemory(&sa,sizeof(SECURITY_ATTRIBUTES));
    sa.nLength=sizeof(SECURITY_ATTRIBUTES);
    STARTUPINFOW si;
    ZeroMemory(&si,sizeof(STARTUPINFOW));
    si.cb=sizeof(STARTUPINFOW);
    PROCESS_INFORMATION pi;
    ZeroMemory(&pi,sizeof(PROCESS_INFORMATION));
    CStringW str= L"\"";
    str=str+cmPath;
    str=str+L"\"";
    str.Replace(L"/",L"\\");

    if(CreateProcessAsUserW(userToken,NULL,str.GetBuffer(),NULL,NULL,false,NULL,NULL,NULL,&si,&pi))
    {
            result=true;
            CloseHandle(pi.hProcess);
            CloseHandle(pi.hThread);
    }
    else
    {
        DWORD err = GetLastError();
        //nop;
    }
}
if(userToken)
    CloseHandle(userToken);
delete[] cmPath;

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

person Raiv    schedule 06.12.2010

Вам следует запускать ваше приложение pscp, используя функцию CreateProcess, а не system. Последний передает вашу команду интерпретатору команд (cmd.exe), который может быть недоступен из службы.

person Alain    schedule 06.12.2010
comment
Я провожу несколько тестов с функцией _popen вместо system, чтобы захватить вывод pscp. Я обнаружил, что программа зависает только при попытке подключения к удаленному хосту. Например, если я запускаю pscp -v (чтобы показать только версию и выйти), он будет работать нормально. - person Augusto Caringi; 07.12.2010
comment
jalf, я так думал. Но я заменил pscp.exe на curl.exe (из libcurl), и это решило мою проблему. - person Augusto Caringi; 08.12.2010

Я исправил проблему!

pscp.exe не работает при запуске из службы. Не знаю почему.

Но curl.exe (из libcurl) поддерживает безопасное копирование!

Спасибо.

person Augusto Caringi    schedule 10.12.2010