对示例的长度感到抱歉,但为了获得服务所需的所有组件,它必须这么长。
在其他人的帮助下,我成功地获得了一个可以干净启动的服务,但现在它不会干净地停止。
第一次尝试快速停止它时会出现错误
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/