windows StartService 失败,错误代码 1053
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1640114/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
StartService fails with error code 1053
提问by kampi
I'm trying to start a process on a remote machine. I'm using OpenSCManager(), CreateService(), QueryServiceStatusEx() and StartService() API-s. I'm able to successfully install my process as a serice, but when i'm trying to start it, StartService returns with errorocode 1053 ("The service didn't respond to the start or control request in a timely fashion."). Can anyone help me to solve this problem?
我正在尝试在远程机器上启动一个进程。我正在使用 OpenSCManager()、CreateService()、QueryServiceStatusEx() 和 StartService() API-s。我能够将我的进程作为服务成功安装,但是当我尝试启动它时,StartService 返回错误代码 1053(“服务没有及时响应启动或控制请求。”)。谁能帮我解决这个问题?
Thanks in advance!
提前致谢!
kampi
坎皮
Update: Here's my code so far(almost from msdn, but i have edited a bit)
更新:到目前为止,这是我的代码(几乎来自 msdn,但我已经编辑了一些)
#include <windows.h>
VOID SvcInstall();
VOID __stdcall DoStartSvc();
#pragma comment(lib, "Advapi32.lib")
SC_HANDLE schSCManager;
SC_HANDLE schService;
int _tmain(int argc, _TCHAR* argv[])
{
SvcInstall();
DoStartSvc();
return 0;
}
VOID SvcInstall()
{
SC_HANDLE schSCManager;
SC_HANDLE schService;
TCHAR szPath[MAX_PATH];
if( !GetModuleFileName( NULL, szPath, MAX_PATH ) )
{
printf("Cannot install service (%d)\n", GetLastError());
return;
}
// Get a handle to the SCM database.
schSCManager = OpenSCManager(
_T("\\kampimachine"), // remote computer
NULL, // ServicesActive database
SC_MANAGER_ALL_ACCESS); // full access rights
if (NULL == schSCManager)
{
printf("OpenSCManager failed (%d)\n", GetLastError());
return;
}
// Create the service
schService = CreateService(
schSCManager, // SCM database
_T("kampi"), // name of service
_T("kampi"), // service name to display
SERVICE_ALL_ACCESS, // desired access
SERVICE_WIN32_OWN_PROCESS, // service type
SERVICE_DEMAND_START, // start type
SERVICE_ERROR_NORMAL, // error control type
_T("%SystemRoot%\system32\notepad.exe"),// path to service's binary
NULL, // no load ordering group
NULL, // no tag identifier
NULL, // no dependencies
_T("domain\user"), // LocalSystem account
_T("password")); // no password
if (schService == NULL)
{
printf("CreateService failed (%d)\n", GetLastError());
CloseServiceHandle(schSCManager);
return;
}
else printf("Service installed successfully\n");
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
}
VOID __stdcall DoStartSvc()
{
SERVICE_STATUS_PROCESS ssStatus;
DWORD dwOldCheckPoint;
DWORD dwStartTickCount;
DWORD dwWaitTime;
DWORD dwBytesNeeded;
// Get a handle to the SCM database.
schSCManager = OpenSCManager(
_T("\\kampimachine"), // remote computer
NULL, // servicesActive database
SC_MANAGER_ALL_ACCESS); // full access rights
if (NULL == schSCManager)
{
printf("OpenSCManager failed (%d)\n", GetLastError());
return;
}
// Get a handle to the service.
schService = OpenService(
schSCManager, // SCM database
_T("kampi"), // name of service
SERVICE_ALL_ACCESS); // full access
if (schService == NULL)
{
printf("OpenService failed (%d)\n", GetLastError());
CloseServiceHandle(schSCManager);
return;
}
// Check the status in case the service is not stopped.
if (!QueryServiceStatusEx(
schService, // handle to service
SC_STATUS_PROCESS_INFO, // information level
(LPBYTE) &ssStatus, // address of structure
sizeof(SERVICE_STATUS_PROCESS), // size of structure
&dwBytesNeeded ) ) // size needed if buffer is too small
{
printf("QueryServiceStatusEx failed (%d)\n", GetLastError());
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
return;
}
// Check if the service is already running. It would be possible
// to stop the service here, but for simplicity this example just returns.
if(ssStatus.dwCurrentState != SERVICE_STOPPED && ssStatus.dwCurrentState != SERVICE_STOP_PENDING)
{
printf("Cannot start the service because it is already running\n");
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
return;
}
// Save the tick count and initial checkpoint.
dwStartTickCount = GetTickCount();
dwOldCheckPoint = ssStatus.dwCheckPoint;
// Wait for the service to stop before attempting to start it.
while (ssStatus.dwCurrentState == SERVICE_STOP_PENDING)
{
// Do not wait longer than the wait hint. A good interval is
// one-tenth of the wait hint but not less than 1 second
// and not more than 10 seconds.
dwWaitTime = ssStatus.dwWaitHint / 10;
if( dwWaitTime < 1000 )
dwWaitTime = 1000;
else if ( dwWaitTime > 10000 )
dwWaitTime = 10000;
Sleep( dwWaitTime );
// Check the status until the service is no longer stop pending.
if (!QueryServiceStatusEx(
schService, // handle to service
SC_STATUS_PROCESS_INFO, // information level
(LPBYTE) &ssStatus, // address of structure
sizeof(SERVICE_STATUS_PROCESS), // size of structure
&dwBytesNeeded ) ) // size needed if buffer is too small
{
printf("QueryServiceStatusEx failed (%d)\n", GetLastError());
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
return;
}
if ( ssStatus.dwCheckPoint > dwOldCheckPoint )
{
// Continue to wait and check.
dwStartTickCount = GetTickCount();
dwOldCheckPoint = ssStatus.dwCheckPoint;
}
else
{
if(GetTickCount()-dwStartTickCount > ssStatus.dwWaitHint)
{
printf("Timeout waiting for service to stop\n");
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
return;
}
}
}
// Attempt to start the service.
if (!StartService(
schService, // handle to service
0, // number of arguments
NULL) ) // no arguments
{
printf("StartService failed (%d)\n", GetLastError());
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
return;
}
else printf("Service start pending...\n");
// Check the status until the service is no longer start pending.
if (!QueryServiceStatusEx(
schService, // handle to service
SC_STATUS_PROCESS_INFO, // info level
(LPBYTE) &ssStatus, // address of structure
sizeof(SERVICE_STATUS_PROCESS), // size of structure
&dwBytesNeeded ) ) // if buffer too small
{
printf("QueryServiceStatusEx failed (%d)\n", GetLastError());
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
return;
}
// Save the tick count and initial checkpoint.
dwStartTickCount = GetTickCount();
dwOldCheckPoint = ssStatus.dwCheckPoint;
while (ssStatus.dwCurrentState == SERVICE_START_PENDING)
{
// Do not wait longer than the wait hint. A good interval is
// one-tenth the wait hint, but no less than 1 second and no
// more than 10 seconds.
dwWaitTime = ssStatus.dwWaitHint / 10;
if( dwWaitTime < 1000 )
dwWaitTime = 1000;
else if ( dwWaitTime > 10000 )
dwWaitTime = 10000;
Sleep( dwWaitTime );
// Check the status again.
if (!QueryServiceStatusEx(
schService, // handle to service
SC_STATUS_PROCESS_INFO, // info level
(LPBYTE) &ssStatus, // address of structure
sizeof(SERVICE_STATUS_PROCESS), // size of structure
&dwBytesNeeded ) ) // if buffer too small
{
printf("QueryServiceStatusEx failed (%d)\n", GetLastError());
break;
}
if ( ssStatus.dwCheckPoint > dwOldCheckPoint )
{
// Continue to wait and check.
dwStartTickCount = GetTickCount();
dwOldCheckPoint = ssStatus.dwCheckPoint;
}
else
{
if(GetTickCount()-dwStartTickCount > ssStatus.dwWaitHint)
{
// No progress made within the wait hint.
break;
}
}
}
// Determine whether the service is running.
if (ssStatus.dwCurrentState == SERVICE_RUNNING)
{
printf("Service started successfully.\n");
}
else
{
printf("Service not started. \n");
printf(" Current State: %d\n", ssStatus.dwCurrentState);
printf(" Exit Code: %d\n", ssStatus.dwWin32ExitCode);
printf(" Check Point: %d\n", ssStatus.dwCheckPoint);
printf(" Wait Hint: %d\n", ssStatus.dwWaitHint);
}
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
}
回答by Jon
There is a good chance that your service is either shutting down immediately or crashing. I would recommend adding some logging information to your service in order to discover why it is exiting.
您的服务很有可能立即关闭或崩溃。我建议向您的服务添加一些日志信息,以发现它退出的原因。
回答by xmoex
I think you are missing a key component here: starting Service Control Dispatcher. As stated in the documentationyou have to start the service control dispatcher in order to enable Windows' Service Control Manager (SCM)to send commands to your service (like SERVICE_CONTROL_STOP
for example)
我认为您在这里缺少一个关键组件:启动Service Control Dispatcher。如文档中所述,您必须启动服务控制调度程序才能启用 Windows 的服务控制管理器 (SCM)向您的服务发送命令(SERVICE_CONTROL_STOP
例如)
Starting the dispatcher is done as follows:
启动调度程序的操作如下:
- create a
SERVICE_TABLE_ENTRY
(look at MSDN library) containing your services' name as well as its Service Main Function(wich is different from your ordinary main method!) - start the Service Control Dispatcherwith this service table entry
- 创建一个
SERVICE_TABLE_ENTRY
(查看 MSDN 库),其中包含您的服务名称及其服务主函数(这与您的普通 main 方法不同!) - 使用此服务表条目启动服务控制调度程序
The background is that every service is being started via SCM, that waits for the service to start its Service Control Dispatcherin order to receive its commands...
背景是每个服务都是通过 SCM 启动的,它等待服务启动其服务控制调度程序以接收其命令......
I see another problem in your code: you're trying to install your service everytime it's being started! You'd better check for appropriate command line arguments to determine if the service is either going to be installed or started!
我在您的代码中看到另一个问题:您每次启动时都试图安装您的服务!您最好检查适当的命令行参数以确定服务是要安装还是启动!
回答by Biswanath Chowdhury
Actually what u r tryin to do is Impersonating the remote pc. If the pc is using Windows XP, then you need priviledges other than Administrator to create services. To adjust priviledges, see the Local system policy in the remote pc. By the way, can u just open the ADMIN$ share in the remote pc from yours? if not, then this is the problem.
实际上你试图做的是模拟远程电脑。如果电脑使用的是 Windows XP,那么您需要管理员以外的权限来创建服务。要调整权限,请参阅远程 PC 中的本地系统策略。顺便问一下,你可以从你的远程电脑上打开 ADMIN$ 共享吗?如果没有,那么这就是问题所在。
for further reference check psexec in sysinternals.
进一步参考检查 sysinternals 中的 psexec。
NO BSOD, No Rootkit ,No Fun -- Biswanath Chowdhury (Win32 Kernel Developer)
没有蓝屏、没有 Rootkit、没有乐趣 -- Biswanath Chowdhury(Win32 内核开发人员)