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

#c #windows #service #installation

#c #Windows #Обслуживание #установка

Вопрос:

У меня есть приложение in 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 successfullyn");
    }

    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)amp;ssp,
        sizeof(SERVICE_STATUS_PROCESS),
        amp;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 successfullyn");

    CloseServiceHandle(schService);
    CloseServiceHandle(schSCManager);
}
  

}

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

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

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

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

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

Комментарии:

1. Что заставляет вас думать, что вам нужно уничтожить экземпляры mmc? Это довольно ужасная вещь для конечного пользователя!

2. Пожалуйста, предоставьте дополнительную информацию. Как вы пытаетесь запустить службу и какое точное сообщение об ошибке? Вы уверены, что szDirectory это содержит полный путь к исполняемому файлу службы, а не (как следует из имени переменной) только путь к каталогу, в котором находится исполняемый файл службы? Каков результат вызова QueryServiceStatusEx при удалении?

3. Кроме того, что делает TraceAdvice()?

Ответ №1:

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