【发布时间】: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