对示例的长度感到抱歉,但为了获得服务的所有必需组件,它必须这么长。
在这里使用其他人的帮助,我设法获得了一个干净启动的服务,但现在它不会干净地停止。
在第一次尝试快速停止它时会出现错误
Could not stop the My service service on local computer
The service did not return an error. This could be an internal Windows error or an internal service error
If the problem persists, contact your system administrator
并且服务继续运行,即使在 sleep 循环需要 5 分钟之后也是如此。
在第二次尝试停止时,任务管理器显示进程立即停止,但服务管理器需要很长时间才能给出错误
Could not stop the My service service on local computer
Error 1053: The service did not respond to the start or control request in a timely fashion.
这是源代码
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <windows.h>
#include <winsvc.h>
#include <time.h>
#define MY_SVC_NAME "My service"
#define THE_PROG "\"C:\\Program Files\\My software\\bin\\The Prog.exe\""
#define SLEEP_TIME 300000
SERVICE_STATUS ServiceStatus;
SERVICE_STATUS_HANDLE hStatus;
void WINAPI ServiceMain(DWORD argc, LPSTR argv);
void WINAPI ControlHandler(DWORD request);
void InitService();
int cont_running = 1;
DWORD WINAPI ServiceHandlerProc(DWORD ControlCode, DWORD a, void *b, void *c)
{
switch (ControlCode) {
case SERVICE_CONTROL_STOP :
cont_running = 0;
ServiceStatus.dwCheckPoint=0;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
ServiceStatus.dwWaitHint =2000;
SetServiceStatus (hStatus, &ServiceStatus);
Sleep(1000);
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus (hStatus, &ServiceStatus);
break;
case SERVICE_CONTROL_SHUTDOWN :
cont_running = 0;
ServiceStatus.dwCheckPoint=0;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
ServiceStatus.dwWaitHint =2000;
SetServiceStatus (hStatus, &ServiceStatus);
Sleep(1000);
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus (hStatus, &ServiceStatus);
break;
}
return 0;
}
void WINAPI ServiceMain(DWORD argc, LPSTR argv)
{
int hServiceStatus;
ServiceStatus.dwServiceType = SERVICE_WIN32;
ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwServiceSpecificExitCode = 0;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
hServiceStatus = RegisterServiceCtrlHandlerEx(MY_SVC_NAME, ServiceHandlerProc,0);
/*
if (hStatus == (SERVICE_STATUS_HANDLE)0) {
return;
}
*/
Sleep(1000);
ServiceStatus.dwCheckPoint=0;
ServiceStatus.dwWaitHint=0;
ServiceStatus.dwCurrentState=SERVICE_RUNNING;
SetServiceStatus( hServiceStatus, &ServiceStatus);
InitService();
return;
}
void InitService()
{
cont_running=1;
do {
system(THE_PROG);
Sleep(SLEEP_TIME);
} while (cont_running);
}
int main(int argc, char *argv[], char *envp[])
{
SERVICE_TABLE_ENTRY ServiceStartTable[2];
ServiceStartTable[0].lpServiceName = MY_SVC_NAME;
ServiceStartTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
ServiceStartTable[1].lpServiceName = NULL;
ServiceStartTable[1].lpServiceProc = NULL;
if (!StartServiceCtrlDispatcher(ServiceStartTable))
{
DWORD err = GetLastError();
if (err == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT)
return 1;
}
return 0;
}
我引用了以下文件但没有成功
http://msdn.microsoft.com/en-us/library/ms809975.aspx
LUA 服务引用手册
最佳答案
问题似乎出在您的 SERVICE_STATUS_HANDLE hStatus
上。全局变量:在程序中没有赋值,但被多次使用。
此外,局部变量 int hServiceStatus
完全没有意义。
解决方法:去掉hServiceStatus
局部变量并替换每次使用 hServiceStatus
使用正确的 hStatus
多变的。
提示:也许你已经意识到这一点,但是你应该在收到控制命令时才设置 STOP_PENDING 状态,只有在你真正停止工作线程时才设置 STOPPED。
关于c - 如何正确使用 SetServiceStatus 告诉 Windows 我的服务正在停止?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8972416/