我使用Visual Studio 2013
在C++
中创建了一个windows service
应用程序。在main()
函数中,调用另一个函数,该函数的函数体包含以下代码::
SERVICE_TABLE_ENTRY SerTable[] =
{
{ const_cast<char *>(ServiceName.c_str()), (LPSERVICE_MAIN_FUNCTION)ServiceMain },
{ NULL, NULL }
};
int res = StartServiceCtrlDispatcher(SerTable);
if (res == 0)
{
DEBUG_LOG(ServiceName+":StartServiceCtrlDispatcher failed", GetLastError());
return QERROR;
}
我的main()函数也包含system("start notepad");
我可以成功地构建程序并生成可执行文件。现在我尝试使用OpenSCManager()
和CreateService()
从另一个程序打开这个exe。这样就创建了服务并将其列在Services.msc
下。我右键单击并启动服务,它显示status
为started
。但是什么也没发生……
现在,如果我双击我的exe
,它显示的消息:error 1063: StartServiceControldispatcher Failed
,然后打开记事本。
为什么在Services.msc
下启动服务时不打开记事本?
您必须从ServiceMain
而不是main
启动记事本。ServiceMain
是操作系统启动服务时调用的函数,因此将system("start notepad")
调用移动到ServiceMain
。
作为OP评论的响应-现在发生的错误是1063或ERROR_FAILED_SERVICE_CONTROLLER_CONNECT
。StartServiceCtrlDispatcher的文档解释说:
如果程序作为控制台应用程序而不是作为服务运行,则返回此错误。
这就是为什么你在双击启动可执行文件时得到错误-你将其作为控制台应用程序启动。当你将正确启动服务(从控制面板,命令提示符或WinAPI)时,该函数将成功。
服务控制管理器启动服务进程时,等待该进程调用StartServiceCtrlDispatcher函数。服务进程的主线程应该在启动后尽快(在30秒内)进行这个调用。如果StartServiceCtrlDispatcher成功,它将调用线程连接到服务控制管理器,并且在进程中所有正在运行的服务进入SERVICE_STOPPED状态之前不会返回。服务控制管理器使用此连接向服务进程的主线程发送控制和服务启动请求。主线程通过调用适当的HandlerEx函数来处理控制请求,或者在新服务启动时创建一个新线程来执行适当的ServiceMain函数,从而充当调度程序。
所以,正确启动后,ServiceMain
将被调用。