【问题标题】:Windows services installation / uninstallation in Windows 10Windows 10 中的 Windows 服务安装/卸载
【发布时间】:2016-10-11 08:57:47
【问题描述】:

我在C++ 中有一个应用程序,它在运行时(此时认为没有其他相关进程正在运行)尝试安装几个服务。

工作流程是,如果服务存在,则将其卸载,否则将其卸载然后重新安装。

我遵循了一些教程,例如: Installing a service

很遗憾,安装或卸载似乎出了点问题。

假设未安装该服务,当我继续安装服务时,它们已安装,然后我尝试更改配置,以延迟自动启动。

在这个阶段,虽然服务已安装,但我无法启动它们,因为我收到错误说服务找不到。

当我尝试卸载服务时,卸载失败,出现错误 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 的调试器中打开...

但它没有用。在我重新启动系统之前,该服务不会被卸载(删除链接到该服务的注册表也不起作用)。

我检查了传递给这些函数的参数,它们看起来是正确的。

我还应该检查什么,以确保正确安装或成功卸载?

【问题讨论】:

  • 是什么让你认为你需要杀死 mmc 实例?这对最终用户来说是一件非常可怕的事情!
  • 请提供更多信息。您如何尝试启动服务,exact 错误消息是什么?您确定szDirectory 包含服务可执行文件的完整 路径,而不是(正如变量名所暗示的)只是服务可执行文件所在目录的路径?卸载时,调用QueryServiceStatusEx的结果是什么?
  • 另外,TraceAdvice() 有什么作用?

标签: c++ windows service installation


【解决方案1】:

你需要先停止服务,否则会卡在这个待删除状态。强制终止服务与停止服务不同。从documentation的同一个区域,你需要ControlService(SERVICE_CONTROL_STOP)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-10
    • 1970-01-01
    • 2018-10-30
    • 2010-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-01
    相关资源
    最近更新 更多