Сбой StartService с кодом ошибки 1053 - PullRequest
0 голосов
/ 29 октября 2009

Я пытаюсь запустить процесс на удаленной машине. Я использую OpenSCManager (), CreateService (), QueryServiceStatusEx () и StartService () API-интерфейсы. Я могу успешно установить свой процесс как службу, но когда я пытаюсь запустить его, StartService возвращается с ошибочным кодом 1053 («Служба не ответила на запрос запуска или управления своевременно».). Может кто-нибудь помочь мне решить эту проблему?

Заранее спасибо!

Kampi

Обновление: вот мой код (почти из 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);
}

Ответы [ 3 ]

1 голос
/ 25 декабря 2011

Я думаю, что вам не хватает ключевого компонента здесь: запуск Диспетчер управления службами . Как указано в документации , необходимо запустить диспетчер управления службами, чтобы Windows * Диспетчер управления службами (SCM) мог отправлять команды в службу (например, SERVICE_CONTROL_STOP). )

Запуск диспетчера осуществляется следующим образом:

  1. создайте SERVICE_TABLE_ENTRY ( посмотрите на библиотеку MSDN ), содержащую название ваших служб, а также основную функцию службы (которая отличается от вашего обычного основного метода!)
  2. запустите Диспетчер управления службами с этой записью в таблице служб

Исходным фоном является то, что каждая служба запускается через SCM, который ожидает, пока служба запустит свой Диспетчер управления службами , чтобы получить свои команды ...

Я вижу еще одну проблему в вашем коде: вы пытаетесь установить службу каждый раз, когда она запускается! Вам лучше проверить соответствующие аргументы командной строки, чтобы определить, будет ли служба установлена ​​или запущена!

1 голос
/ 29 октября 2009

Существует большая вероятность того, что ваш сервис либо сразу отключится, либо выйдет из строя. Я бы порекомендовал добавить некоторую информацию о регистрации в ваш сервис, чтобы выяснить, почему он выходит.

0 голосов
/ 01 марта 2011

На самом деле вы пытаетесь выдать себя за удаленный компьютер. Если компьютер использует Windows XP, вам нужны привилегии, отличные от Администратора, для создания сервисов. Чтобы настроить привилегии, см. Политику локальной системы на удаленном компьютере. Кстати, вы можете просто открыть с вашего компьютера общий ресурс ADMIN $ на удаленном компьютере? если нет, то это проблема.

для дальнейшей проверки psexec в sysinternals.

НЕТ BSOD, Нет руткитов, нет веселья - Бисванат Чоудхури (разработчик ядра Win32)

...