[英]how to run more than one windows service in a single program
我需要在一个程序中运行两个不同的服务。 当我尝试只执行一项服务时,我可以启动另一项我无法启动的服务。
下面是代码:
这是我注册为入口点的 servicemain:
VOID WINAPI ServiceMain1 (DWORD argc, LPTSTR *argv)
{
DWORD Status = E_FAIL;
// Register our service control handler with the SCM
g_StatusHandleEA3 = RegisterServiceCtrlHandler (EA3_SERVICE_NAME, ServiceCtrlHandlerEA3);
if (g_StatusHandleEA3 == NULL)
{
goto EXIT;
}
// Tell the service controller we are starting
ZeroMemory (&g_ServiceStatusEA3, sizeof (g_ServiceStatusEA3));
g_ServiceStatusEA3.dwServiceType = SERVICE_WIN32_SHARE_PROCESS;
g_ServiceStatusEA3.dwControlsAccepted = 0;
g_ServiceStatusEA3.dwCurrentState = SERVICE_START_PENDING;
g_ServiceStatusEA3.dwWin32ExitCode = 0;
g_ServiceStatusEA3.dwServiceSpecificExitCode = 0;
g_ServiceStatusEA3.dwCheckPoint = 0;
if (SetServiceStatus (g_StatusHandleEA3 , &g_ServiceStatusEA3) == FALSE)
{
OutputDebugString(_T(
"My Sample Service: ServiceMain: SetServiceStatus returned error"));
}
/*
* Perform tasks necessary to start the service here
*/
// Create a service stop event to wait on later
g_ServiceStopEventEA3 = CreateEvent (NULL, TRUE, FALSE, NULL);
if (g_ServiceStopEventEA3 == NULL)
{
// Error creating event
// Tell service controller we are stopped and exit
g_ServiceStatusEA3.dwControlsAccepted = 0;
g_ServiceStatusEA3.dwCurrentState = SERVICE_STOPPED;
g_ServiceStatusEA3.dwWin32ExitCode = GetLastError();
g_ServiceStatusEA3.dwCheckPoint = 1;
if (SetServiceStatus (g_StatusHandleEA3, &g_ServiceStatusEA3) == FALSE)
{
OutputDebugString(_T(
"My Sample Service: ServiceMain: SetServiceStatus returned error"));
}
goto EXIT;
}
// Tell the service controller we are started
g_ServiceStatusEA3.dwControlsAccepted = SERVICE_ACCEPT_STOP;
g_ServiceStatusEA3.dwCurrentState = SERVICE_RUNNING;
g_ServiceStatusEA3.dwWin32ExitCode = 0;
g_ServiceStatusEA3.dwCheckPoint = 0;
if (SetServiceStatus (g_StatusHandleEA3, &g_ServiceStatusEA3) == FALSE)
{
OutputDebugString(_T(
"My Sample Service: ServiceMain: SetServiceStatus returned error"));
}
// Start a thread that will perform the main task of the service
HANDLE hThread = CreateThread (NULL, 0, ServiceWorkerThread, NULL, 0, NULL);
// Wait until our worker thread exits signaling that the service needs to stop
WaitForSingleObject (hThread, INFINITE);
/*
* Perform any cleanup tasks
*/
CloseHandle (g_ServiceStopEventEA3);
// Tell the service controller we are stopped
g_ServiceStatusEA3.dwControlsAccepted = 0;
g_ServiceStatusEA3.dwCurrentState = SERVICE_STOPPED;
g_ServiceStatusEA3.dwWin32ExitCode = 0;
g_ServiceStatusEA3.dwCheckPoint = 3;
if (SetServiceStatus (g_StatusHandleEA3, &g_ServiceStatusEA3) == FALSE)
{
OutputDebugString(_T(
"My Sample Service: ServiceMain: SetServiceStatus returned error"));
}
EXIT:
return;
}
这是第二个入口点:
VOID WINAPI ServiceMain2 (DWORD argc, LPTSTR *argv)
{
DWORD Status = E_FAIL;
// Register our service control handler with the SCM
g_StatusHandleEAT = RegisterServiceCtrlHandler (EAT_SERVICE_NAME, ServiceCtrlHandlerEAT);
if (g_StatusHandleEAT == NULL)
{
goto EXIT;
}
// Tell the service controller we are starting
ZeroMemory (&g_ServiceStatusEAT, sizeof (g_ServiceStatusEAT));
g_ServiceStatusEAT.dwServiceType = SERVICE_WIN32_SHARE_PROCESS;
g_ServiceStatusEAT.dwControlsAccepted = 0;
g_ServiceStatusEAT.dwCurrentState = SERVICE_START_PENDING;
g_ServiceStatusEAT.dwWin32ExitCode = 0;
g_ServiceStatusEAT.dwServiceSpecificExitCode = 0;
g_ServiceStatusEAT.dwCheckPoint = 0;
if (SetServiceStatus (g_StatusHandleEAT , &g_ServiceStatusEAT) == FALSE)
{
OutputDebugString(_T(
"My Sample Service: ServiceMain: SetServiceStatus returned error"));
}
/*
* Perform tasks necessary to start the service here
*/
// Create a service stop event to wait on later
g_ServiceStopEventEAT = CreateEvent (NULL, TRUE, FALSE, NULL);
if (g_ServiceStopEventEAT == NULL)
{
// Error creating event
// Tell service controller we are stopped and exit
g_ServiceStatusEAT.dwControlsAccepted = 0;
g_ServiceStatusEAT.dwCurrentState = SERVICE_STOPPED;
g_ServiceStatusEAT.dwWin32ExitCode = GetLastError();
g_ServiceStatusEAT.dwCheckPoint = 1;
if (SetServiceStatus (g_StatusHandleEAT, &g_ServiceStatusEAT) == FALSE)
{
OutputDebugString(_T(
"My Sample Service: ServiceMain: SetServiceStatus returned error"));
}
goto EXIT;
}
// Tell the service controller we are started
g_ServiceStatusEAT.dwControlsAccepted = SERVICE_ACCEPT_STOP;
g_ServiceStatusEAT.dwCurrentState = SERVICE_RUNNING;
g_ServiceStatusEAT.dwWin32ExitCode = 0;
g_ServiceStatusEAT.dwCheckPoint = 0;
if (SetServiceStatus (g_StatusHandleEAT, &g_ServiceStatusEAT) == FALSE)
{
OutputDebugString(_T(
"My Sample Service: ServiceMain: SetServiceStatus returned error"));
}
// Start a thread that will perform the main task of the service
HANDLE hThread = CreateThread (NULL, 0, ServiceWorkerThread1, NULL, 0, NULL);
// Wait until our worker thread exits signaling that the service needs to stop
WaitForSingleObject (hThread, INFINITE);
/*
* Perform any cleanup tasks
*/
CloseHandle (g_ServiceStopEventEAT);
// Tell the service controller we are stopped
g_ServiceStatusEAT.dwControlsAccepted = 0;
g_ServiceStatusEAT.dwCurrentState = SERVICE_STOPPED;
g_ServiceStatusEAT.dwWin32ExitCode = 0;
g_ServiceStatusEAT.dwCheckPoint = 3;
if (SetServiceStatus (g_StatusHandleEAT, &g_ServiceStatusEAT) == FALSE)
{
OutputDebugString(_T(
"My Sample Service: ServiceMain: SetServiceStatus returned error"));
}
EXIT:
return;
}
以下是我的调用方式:
int main()
{
SERVICE_TABLE_ENTRY ServiceTable[] =
{
{EA3_SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION) ServiceMain1},
{EAT_SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION) ServiceMain2},
{NULL, NULL}
};
if (StartServiceCtrlDispatcher (ServiceTable) == FALSE)
{
return GetLastError ();
}
return 0;
}
请帮助我,我是 C++ 编程的新手。
下面是服务控制处理程序:
VOID WINAPI ServiceCtrlHandlerEAT (DWORD CtrlCode)
{
switch (CtrlCode)
{
case SERVICE_CONTROL_STOP :
if (g_ServiceStatusEAT.dwCurrentState != SERVICE_RUNNING)
break;
/*
* Perform tasks necessary to stop the service here
*/
g_ServiceStatusEAT.dwControlsAccepted = 0;
g_ServiceStatusEAT.dwCurrentState = SERVICE_STOP_PENDING;
g_ServiceStatusEAT.dwWin32ExitCode = 0;
g_ServiceStatusEAT.dwCheckPoint = 4;
if (SetServiceStatus (g_StatusHandleEAT, &g_ServiceStatusEAT) == FALSE)
{
OutputDebugString(_T(
"My Sample Service: ServiceCtrlHandler: SetServiceStatus returned error"));
}
// This will signal the worker thread to start shutting down
SetEvent (g_ServiceStopEventEAT);
break;
default:
break;
}
}
VOID WINAPI ServiceCtrlHandlerEA3 (DWORD CtrlCode)
{
switch (CtrlCode)
{
case SERVICE_CONTROL_STOP :
if (g_ServiceStatusEA3.dwCurrentState != SERVICE_RUNNING)
break;
/*
* Perform tasks necessary to stop the service here
*/
g_ServiceStatusEA3.dwControlsAccepted = 0;
g_ServiceStatusEA3.dwCurrentState = SERVICE_STOP_PENDING;
g_ServiceStatusEA3.dwWin32ExitCode = 0;
g_ServiceStatusEA3.dwCheckPoint = 4;
if (SetServiceStatus (g_StatusHandleEA3, &g_ServiceStatusEA3) == FALSE)
{
OutputDebugString(_T(
"My Sample Service: ServiceCtrlHandler: SetServiceStatus returned error"));
}
// This will signal the worker thread to start shutting down
SetEvent (g_ServiceStopEventEA3);
break;
default:
break;
}
}
RegisterServiceCtrlHandler (EA3_SERVICE_NAME, ServiceCtrlHandler);
您尚未显示ServiceCtrlHandler
的代码,但正如我所见,您对这两个服务使用相同的 proc(这可能是您的错误所在)。 操作系统使用此过程来启动/停止等您的服务,因此您必须相应地对其进行编码。 完成后,您将能够使用控制面板等启动/停止您的任何服务。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.