我正在用C ++(Visual Studio 2010)编写Windows服务,此服务必须通过安全副本将文件发送到远程服务器(我正在使用pscp.exe)。
所以,我正在使用system
函数启动pscp.exe,当作为普通应用程序运行时,一切正常。
但是,如果我尝试作为服务运行,服务启动pscp.exe(我可以在任务管理器上看到这一点),但pscp.exe冻结并且不向远程主机发送任何内容。即使我停止服务,我也需要自己杀死pscp进程。
我在一些论坛中读到允许服务“与桌面交互”,但这并没有解决我的问题。
我还尝试更改服务登录的用户帐户,但没有结果。
有什么想法吗?
从Windows服务运行外部程序似乎非常困难,即使此外部程序没有任何GUI,例如pscp.exe。
谢谢!
- Augusto Caringi
答案 0 :(得分:0)
pscp
调用有哪些选择?如果存在“静默”选项,请使用该选项以避免控制台交互。通常,这是-q
或/q
。
请注意,任何已启动的应用都将在与您的服务相同的用户帐户中运行。该帐户是否有权执行您的要求?上下文(运行目录,路径)是否正确pscp
做你想做的事情?
答案 1 :(得分:0)
您可以尝试使用模仿。像这样......
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;
这段代码用于从服务中调用GUI应用程序,但我认为控制台应用程序无需进行太多更改。
答案 2 :(得分:0)
您应该使用CreateProcess函数而不是system来启动pscp应用程序。后者将您的命令中继到命令解释器(cmd.exe),该命令解释器可能无法从服务访问。
答案 3 :(得分:0)
我解决了这个问题!
pscp.exe无法从服务运行。我不知道为什么。
但curl.exe(来自libcurl)可以,它支持安全拷贝!
感谢。