开发者

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

开发者 https://www.devze.com 2023-01-28 22:22 出处:网络
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).

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号