gpt4 book ai didi

c - 如何正确使用SetServiceStatus告诉Windows我的服务正在停止?

转载 作者:行者123 更新时间:2023-11-30 14:26:33 25 4
gpt4 key购买 nike

对示例的长度感到抱歉,但为了获得服务所需的所有组件,它必须这么长。

在其他人的帮助下,我成功地获得了一个可以干净启动的服务,但现在它不会干净地停止。

第一次尝试快速停止它时会出现错误

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.aspxLUA服务引用手册

最佳答案

问题似乎出在您的 SERVICE_STATUS_HANDLE hStatus 全局变量上:它没有在程序中的任何位置分配,但使用了很多次。

此外,局部变量 int hServiceStatus 根本没有任何意义。

解决方案:删除 hServiceStatus 局部变量,并将每次使用 hServiceStatus 替换为正确的 hStatus 变量。

提示:也许您已经意识到这一点,但您应该在收到控制命令时设置 STOP_PENDING 状态,并仅在真正停止工作线程时设置 STOPPED。

关于c - 如何正确使用SetServiceStatus告诉Windows我的服务正在停止?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8972416/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com