Запуск внешней программы (pscp) из службы Windows не работает - PullRequest
0 голосов
/ 06 декабря 2010

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

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

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

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

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

Есть идеи?

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

Спасибо!

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

Ответы [ 4 ]

0 голосов
/ 10 декабря 2010

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

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

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

Спасибо.

0 голосов
/ 06 декабря 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;

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

0 голосов
/ 07 декабря 2010

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

0 голосов
/ 06 декабря 2010

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

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

...