15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


Запуск сервиса.

Ниже представлен пример, который для запуска сервиса открывает дескриптор сервиса из базы сервисов, а затем передаёт его в функцию StartService. После запуска сервиса, пример использует структуру SERVICE_STATUS, возвращаемую функцией QueryServiceStatus, чтобы получить состояние сервиса.

 

DWORD StartSampleService()
{
    SERVICE_STATUS ssStatus;
    DWORD dwOldCheckPoint;
    DWORD dwStartTickCount;
    DWORD dwWaitTime;
    DWORD dwStatus;

    schService = OpenService(
        schSCManager,          // база сервисов SCM
        "Sample_Srv",          // имя сервиса
        SERVICE_ALL_ACCESS);

    if (schService == NULL)
    {
        MyErrorExit("OpenService");
    }

    if (!StartService(
            schService,  // дескриптор сервиса
            0,           // количество аргументов
            NULL) )      // нет аргументов
    {
        MyErrorExit("StartService");
    }
    else
    {
        printf("Service start pending.\n");
    }

    // Проверяем состояние сервиса до тех пор, пока он не запустится.

    if (!QueryServiceStatus(
            schService,   // дескриптор сервиса
            &ssStatus) )  // адрес структуры с информацией о сервисе
    {
        MyErrorExit("QueryServiceStatus");
    }

    // Сохраняем счётчик тиков и начальную точку.

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

    while (ssStatus.dwCurrentState == SERVICE_START_PENDING)
    {
        // Не нужно ожидать дольше, чем приблизительное время,
        // необходимое для старта. Обычно ожидать лучше всего одну
        // десятую этого значения, но не более одно секунды
        // и никак не более 10 секунд.

        dwWaitTime = ssStatus.dwWaitHint / 10;

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

        Sleep( dwWaitTime );

        // Снова проверяем статус.

        if (!QueryServiceStatus(
                schService,   // дескриптор сервиса
                &ssStatus) )  // адрес структуры
            break;

        if ( ssStatus.dwCheckPoint > dwOldCheckPoint )
        {
            // Сервис в процесса старта.

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

    if (ssStatus.dwCurrentState == SERVICE_RUNNING)
    {
        printf("StartService SUCCESS.\n");
        dwStatus = NO_ERROR;
    }
    else
    {
        printf("\nСервис на запущен. \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);
        dwStatus = GetLastError();
    }

    CloseServiceHandle(schService);
    return dwStatus;
}