Запуск службы

Чтобы запустить службу, в примере ниже открывается дескриптор установленной базы данных, а затем задается дескриптор при вызове функции StartService. Он может использоваться, чтобы запустить или службу, или сервисный драйвер, но этот пример предполагает, что служба запущена. После запуска службы, программа использует члены структуры SERVICE_STATUS_PROCESS, возвращенные функцией QueryServiceStatusEx, чтобы отслеживать ход запуска службы.

Функция требует дескриптора базы данных диспетчера управления службами. Дополнительную информацию смотри в статье Открытие базы данных SCManager .

#include <windows.h>
#include <stdio.h>

BOOL StartSampleService(SC_HANDLE schSCManager) 
{ 
    SC_HANDLE schService;
    SERVICE_STATUS_PROCESS ssStatus; 
    DWORD dwOldCheckPoint; 
    DWORD dwStartTickCount;
    DWORD dwWaitTime;
    DWORD dwBytesNeeded;
 
    schService = OpenService( 
        schSCManager,          // база данных SCM
        "Sample_Srv",          // имя службы
        SERVICE_ALL_ACCESS); 
 
    if (schService == NULL) 
    { 
        return 0; 
    }
 
    if (!StartService(
            schService,  // дескриптор службы 
            0,           // число параметров 
            NULL) )      // параметров нет
    {
        return 0; 
    }
    else 
    {
        printf("Service start pending.\n"); 
    }
 
    // Проверяем состояние до тех пор, пока служба больше не ожидает запуска. 
 
    if (!QueryServiceStatusEx( 
            schService,             // дескриптор службы 
            SC_STATUS_PROCESS_INFO, // уровень информации
            &ssStatus               // адрес структуры с информацией о статусе
            sizeof(STATUS_PROCESS_INFO), 
            &dwBytesNeeded ) )      // если слишком маленький буфер
    {
        return 0; 
    }
 
    // Сохраним подсчет импульсов сигнала времени и первоначальную контрольную точку.

    dwStartTickCount = GetTickCount();
    dwOldCheckPoint = ssStatus.dwCheckPoint;

    while (ssStatus.dwCurrentState == SERVICE_START_PENDING) 
    { 
        // Не ждите дольше чем указано ожидать. Хороший интервал - 
        // одна десятая от указанного времени ожидания, но никакая меньше чем 1 секунда 
        // и никак не больше, чем 10 секунд. 
 
        dwWaitTime = ssStatus.dwWaitHint / 10;

        if( dwWaitTime < 1000 )
            dwWaitTime = 1000;
        else if ( dwWaitTime > 10000 )
            dwWaitTime = 10000;

        Sleep( dwWaitTime );

        // Проверьте состояние снова. 
 
    if (!QueryServiceStatusEx( 
            schService,             // дескриптор службы 
            SC_STATUS_PROCESS_INFO, // уровень информации
            &ssStatus               // адрес структуры с информацией о статусе
            sizeof(STATUS_PROCESS_INFO), 
            &dwBytesNeeded ) )      // если слишком маленький буфер
            break; 
 
        if ( ssStatus.dwCheckPoint > dwOldCheckPoint )
        {
            // Служба создает индикацию протекания процесса.

            dwStartTickCount = GetTickCount();
            dwOldCheckPoint = ssStatus.dwCheckPoint;
        }
        else
        {
            if(GetTickCount()-dwStartTickCount > ssStatus.dwWaitHint)
            {
                // В рамках ожидания указания индикацию протекания процесса не делать.
                break;
            }
        }
    } 

    CloseServiceHandle(schService); 

    if (ssStatus.dwCurrentState == SERVICE_RUNNING) 
    {
        printf("StartService SUCCESS.\n"); 
        return 1;
    }
    else 
    { 
        printf("\nService not started. \n");
        printf("  Current State: %d\n", ssStatus.dwCurrentState); 
        printf("  Exit Code: %d\n", ssStatus.dwWin32ExitCode); 
        printf("  Service Specific Exit Code: %d\n", 
            ssStatus.dwServiceSpecificExitCode); 
        printf("  Check Point: %d\n", ssStatus.dwCheckPoint); 
        printf("  Wait Hint: %d\n", ssStatus.dwWaitHint); 
        return 0;
    } 
}

Назад в оглавление
На главную страницу

Hosted by uCoz