Установка/удаление служб Windows в Windows 10

У меня есть приложение в C++, которое пытается после запуска (в это время не считается, что какой-либо другой соответствующий процесс запущен) установить пару служб.

Рабочий процесс заключается в том, что если службы существуют, то они удаляются, в противном случае они удаляются, а затем переустанавливаются.

Я следовал нескольким руководствам, таким как: Установка службы< /а>

К сожалению, что-то пошло не так с установкой или удалением.

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

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

Когда я пытаюсь удалить службы, происходит сбой удаления, выдается ошибка 1060, говорящая о том, что службы помечены для удаления.

SC_HANDLE schSCManager;
SC_HANDLE schService;

schSCManager = OpenSCManager(
    NULL,                    // local computer
    NULL,                    // ServicesActive database 
    SC_MANAGER_ALL_ACCESS);  // full access rights 

if (schSCManager == nullptr)
{
    continue;
}
if (bInstall)
{
    schService = CreateService(
        schSCManager,              // SCM database 
        szServiceName,                   // name of service 
        szDisplayName,                   // 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 
        szDirectory,                    // path to service's binary 
        NULL,                      // no load ordering group 
        NULL,                      // no tag identifier 
        NULL,                      // no dependencies 
        NULL,                      // LocalSystem account 
        NULL);                     // no password 

    if (schService == NULL)
    {
        TraceAdvice(L"CreateService failed (%d)\n", GetLastError());

        CloseServiceHandle(schSCManager);
        continue;
    }
    else
    {
        if (!ChangeServiceConfig(
            schService,            // handle of service 
            SERVICE_NO_CHANGE,     // service type: no change 
            SERVICE_CONFIG_DELAYED_AUTO_START_INFO,  // service start type 
            SERVICE_NO_CHANGE,     // error control: no change 
            NULL,                  // binary path: no change 
            NULL,                  // load order group: no change 
            NULL,                  // tag ID: no change 
            NULL,                  // dependencies: no change 
            NULL,                  // account name: no change 
            NULL,                  // password: no change 
            NULL))                // display name: no change
        {
            TraceAdvice(L"ChangeServiceConfig failed (%d)\n", GetLastError());
        }
        TraceAdvice(L"Service installed successfully\n");
    }

    CloseServiceHandle(schService);
    CloseServiceHandle(schSCManager);
    /*TraceFatal(_T("Now installing : %s"), szServiceName);
    _stprintf_s(szTmp, _T("SC create %s binpath= \"%s%s.exe\" displayName= \"%s\"  start= delayed-auto"), szServiceName, szDirectory, szServiceName, szDisplayName);
    TraceFatal(_T("Command is : %s"), szTmp);*/
}
else
{

    _wsystem(_T("taskkill /F /IM mmc.exe")); // Need to kill any instance of MMC running
    _wsystem(_T("taskkill /F /IM procexp.exe")); 

    schService = OpenService(
        schSCManager,       // SCM database 
        szServiceName,          // name of service 
        DELETE);            // need delete access 

    if (schService == NULL)
    {
        TraceAdvice(L"OpenService failed (%d)\n", GetLastError());
        CloseServiceHandle(schSCManager);
        continue;
    }

    DWORD dwBytesNeeded;
    SERVICE_STATUS_PROCESS ssp;

    if (!QueryServiceStatusEx(
        schService,
        SC_STATUS_PROCESS_INFO,
        (LPBYTE)&ssp,
        sizeof(SERVICE_STATUS_PROCESS),
        &dwBytesNeeded))
    {
        printf("QueryServiceStatusEx failed (%d)\n", GetLastError());
    }
    if (ssp.dwCurrentState == SERVICE_RUNNING)
    {
        _stprintf_s(szTmp, _T("taskkill /F /IM %s.exe"), szServiceName);
        _wsystem(szTmp);
    }
    // Delete the service.

    if (!DeleteService(schService))
    {
        TraceAdvice(L"DeleteService failed (%d)\n", GetLastError());
    }
    else TraceAdvice(L"Service deleted successfully\n");

    CloseServiceHandle(schService);
    CloseServiceHandle(schSCManager);
}

}

Я убедился во всех пунктах, а именно.

  • Диспетчер задач был закрыт
  • Сервисная консоль была закрыта.
  • Все экземпляры MMC были закрыты.
  • Служба была остановлена
  • Служба не была открыта в отладчике в Visual Studio...

Но это не помогает. Служба не удаляется, пока я не перезагружу систему (удаление реестра, связанного со службой, также не работает).

Я проверил параметры, которые я передаю этим функциям, и они кажутся правильными.

Что еще я должен проверить, чтобы обеспечить правильную установку или успешное удаление?


person user1173240    schedule 11.10.2016    source источник
comment
Что заставляет вас думать, что вам нужно убивать экземпляры mmc? Это довольно ужасная вещь для конечного пользователя!   -  person Harry Johnston    schedule 12.10.2016
comment
Больше информации, пожалуйста. Как вы пытаетесь запустить службу и какое точное сообщение об ошибке? Вы уверены, что szDirectory содержит полный путь к исполняемому файлу службы, а не (как следует из имени переменной) только путь к каталогу, в котором находится исполняемый файл службы? При удалении каков результат вызова QueryServiceStatusEx?   -  person Harry Johnston    schedule 12.10.2016
comment
Кроме того, что делает TraceAdvice()?   -  person Harry Johnston    schedule 12.10.2016


Ответы (1)


Сначала вам нужно остановить службу, иначе она застрянет в этом состоянии ожидания удаления. Принудительно убить службу — это не то же самое, что остановить ее. Из той же области документации вы нужно ControlService(SERVICE_CONTROL_STOP).

person Luke    schedule 11.10.2016