问题
我想使用 Windows API 控制任何 Windows 服务,但我不能:(
= 我的“想要的解决方案”有什么问题?
当前解决方案
我使用的最丑陋但实用的方法如下(用于 Stop
命令):
void StopService()
{
ShellExecute(Application->Handle,
"open",
"stop.bat",
NULL,
ExtractFilePath(Application->ExeName).c_str(),
SW_SHOW);
}
其中 stop.bat
是一个包含以下命令的 Windows 批处理文件:
::the command
sc stop "service name"
::a pause to see if something goes wrong
pause
必须关闭已启动的 cmd 窗口非常烦人...
想要解决方案
下面的函数似乎没问题。如果我尝试执行命令来停止不存在的服务,它会显示一条错误消息。但是当我尝试为现有服务运行它时,它运行了,但该服务没有任何反应(如果我命令停止它,它什么也不做)...
void ControlService(AnsiString ServiceName, DWORD Order)
{
SC_HANDLE Scm, Svc;
SERVICE_STATUS Status;
Scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if(Scm != 0)
{
Svc = OpenService(Scm, PChar(ServiceName.c_str()), SERVICE_ALL_ACCESS);
if(Svc != 0)
{
ControlService(Svc, Order, &Status);
// handle Status....
CloseServiceHandle(Svc);
}
else
{
ShowLastError();
}
CloseServiceHandle(Scm);
}
else
{
ShowLastError();
}
}
void ShowLastError()
{
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
// Display the string.
MessageBox(NULL, (char*)lpMsgBuf, "GetLastError", MB_OK|MB_ICONINFORMATION);
// Free the buffer.
LocalFree(lpMsgBuf);
}
怎么了????
最佳答案
您可能遇到的两个可能问题:
- 您检查服务状态的时间过早。 ServiceControl 立即返回,无需等待服务完成请求。您的服务可能会转换为 SERVICE_STOP_PENDING,在这种情况下,您必须给它一些时间并再次检查。
- 有处于运行状态的依赖服务。您将不得不枚举相关服务,先关闭它们,然后停止您的服务。
在#2 上,MSDN 上的示例代码有很好的解释.这是来自同一页面的引述:
However, if the SCM determines that other running services are dependent on the specified service, it will not forward the stop request. Instead, it returns ERROR_DEPENDENT_SERVICES_RUNNING. Therefore, to programmatically stop such a service, you must first enumerate and stop its dependent services.
关于c++ - 如何使用Windows API轻松控制Windows服务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16898066/