简体   繁体   中英

Running a external program (pscp) from a Windows Service doesn't works

I'm writing a Windows Service in C++ (Visual Studio 2010) and this service must send a file to a remote server through secure copy (I'm using pscp.exe for that).

So, I'm using the system function to launch pscp.exe and when running as a normal application all works fine.

But if I try to run as a service, the service launch pscp.exe (I can see this on Task Manager), but the pscp.exe freezes and don't send anything to the remote host. And even if I stop the service, I need to kill the pscp process by myself.

I read in some forums to allow the service to "Interact with Desktop", but this doesn't resolved my problem.

I also tried to change the user account that the service log on as, with no results.

Any ideas?

It seems that is very difficult to run a external program from a Windows Service, even if this external program doesn't have any GUI, like pscp.exe.

Thanks!

-- Augusto Caringi

What are your options on the pscp invocation? If there is a 'silent' option, use that to avoid console interaction. Often, this is -q or /q .

Be aware that any launched app will run in the same user account as your service. Does that account have permissions to do what you are asking of it? Is the context (run directory, path) correct for pscp to do what you want?

You may try to use impersonate. Something like this...

    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;

this piece of code i use to call GUI application from service, but i think it need not much changes for console app.

You should launch your pscp application using the CreateProcess function rather than system. The latter relay your command to the command interpreter (cmd.exe), which might not be accessible from a service.

I fixed the problem!

pscp.exe does not work running from a service. I don't know why.

But curl.exe (from libcurl) does and it support secure copy!

Thanks.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM