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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 13:21:00  来源:igfitidea点击:

StartService fails with error code 1053

c++windowsremoting

提问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_STOPfor example)

我认为您在这里缺少一个关键组件:启动Service Control Dispatcher。如文档中所述,您必须启动服务控制调度程序才能启用 Windows 的服务控制管理器 (SCM)向您的服务发送命令(SERVICE_CONTROL_STOP例如)

Starting the dispatcher is done as follows:

启动调度程序的操作如下:

  1. 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!)
  2. start the Service Control Dispatcherwith this service table entry
  1. 创建一个SERVICE_TABLE_ENTRY查看 MSDN 库),其中包含您的服务名称及其服务主函数(这与您的普通 main 方法不同!)
  2. 使用此服务表条目启动服务控制调度程序

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 内核开发人员)