无法使用StartServiceCtrlDispatcher在一个exe中启动多个Windows服务

时间:2016-04-09 03:58:28

标签: c++ windows windows-services

我正在运行多个Windows服务,但是当我给sc启动“svc name”时它只运行第一个服务.Below是相同的代码片段,任何我输错的输入都会有很大的帮助。

这里只启动了第一个服务my_SERVICE_NAME。

#include "MyService.h"
#include <string>
#include<iostream>
#include<Windows.h>
#include<tchar.h>

static int ismyStarted = 0;
static int ismy1Started = 0;
VOID WINAPI ServiceMain(DWORD argc, LPTSTR *argv)
{
DWORD Status = E_FAIL;

// Register our service control handler with the SCM
g_StatusHandle = RegisterServiceCtrlHandler(my_SERVICE_NAME, ServiceCtrlHandler);

if(g_StatusHandle == NULL)
{
goto EXIT;
}

// Tell the service controller we are starting
ZeroMemory(&g_ServiceStatus, sizeof(g_ServiceStatus));
g_ServiceStatus.dwServiceType = SERVICE_WIN32_SHARE_PROCESS ;
//g_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_SHUTDOWN;
g_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
g_ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
g_ServiceStatus.dwWin32ExitCode = 0;
g_ServiceStatus.dwServiceSpecificExitCode = 0;
g_ServiceStatus.dwCheckPoint = 0;

if(SetServiceStatus(g_StatusHandle, &g_ServiceStatus) == FALSE)
{
debugLog("d:\my_logs.txt", "Unable to set event in line ");
}

/*
* Perform tasks necessary to start the service here
*/

// Create a service stop event to wait on later
g_ServiceStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if(g_ServiceStopEvent == NULL)
{
// Error creating event
// Tell service controller we are stopped and exit
g_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_SHUTDOWN;
g_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
g_ServiceStatus.dwWin32ExitCode = GetLastError();
g_ServiceStatus.dwCheckPoint = 1;

if(SetServiceStatus(g_StatusHandle, &g_ServiceStatus) == FALSE)
{
debugLog("d:\my_logs.txt", "Unable to set event in line ");
}
goto EXIT;
}

// Tell the service controller we are started
//g_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_SHUTDOWN;
g_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
g_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
g_ServiceStatus.dwWin32ExitCode = 0;
g_ServiceStatus.dwCheckPoint = 0;

if(SetServiceStatus(g_StatusHandle, &g_ServiceStatus) == FALSE)
{
debugLog("d:\my_logs.txt", "Unable to set event in line ");
}

// Start a thread that will perform the main task of the service
debugLog("d:\my_logs.txt", "starting worker thread ");
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_ServiceStopEvent);

// Tell the service controller we are stopped
//g_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_SHUTDOWN;
g_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
g_ServiceStatus.dwWin32ExitCode = 0;
g_ServiceStatus.dwCheckPoint = 3;

if(SetServiceStatus(g_StatusHandle, &g_ServiceStatus) == FALSE)
{
debugLog("d:\my_logs.txt", "Unable to set event in line ");
}

EXIT: return;
}
VOID WINAPI ServiceCtrlHandler(DWORD CtrlCode)
{

switch(CtrlCode)
{
case SERVICE_CONTROL_STOP:

if(g_ServiceStatus.dwCurrentState != SERVICE_RUNNING)
break;

/*
* Perform tasks necessary to stop the service here
*/

//g_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_SHUTDOWN;
g_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
g_ServiceStatus.dwWin32ExitCode = 0;
g_ServiceStatus.dwCheckPoint = 4;

if(SetServiceStatus(g_StatusHandle, &g_ServiceStatus) == FALSE)
{
debugLog("d:\my_logs.txt", "my:Unable to set event in line ");
}

// This will signal the worker thread to start shutting down
if(! SetEvent(g_ServiceStopEvent))
{
debugLog("d:\my_logs.txt", "my:Not Stopped Service ");
}
else
{
debugLog("d:\my_logs.txt", "my: Stopped Service ");
}

break;

default:
break;
}
}
DWORD WINAPI ServiceWorkerThread(LPVOID lpParam)
{
while(true)
{
if(0 == ismyStarted)
{
debugLog("d:\my_logs.txt"," ismyStarted ",ismyStarted);
int iRet = createProcess();
ismyStarted = 1;
if(-1 == iRet)
{
debugLog("d:\my_logs.txt", "Create process failed!");
break;
}
}
HANDLE handles[2];
handles[0] = pi.hProcess;
handles[1] = g_ServiceStopEvent;
DWORD dwRet = WaitForMultipleObjects(2, handles, false, INFINITE);
if(WAIT_OBJECT_0 == dwRet)
{
debugLog("d:\my_logs.txt", "my server down");
ismyStarted = 0;
continue;
}
if(WAIT_OBJECT_0 + 1 == dwRet)
{
//debugLog("d:\my_logs.txt", "Service stop received");
if(pi.hProcess != NULL)
{
//debugLog("d:\my_logs.txt", "KIlling!! ",pi.dwProcessId);
if(!TerminateProcess(pi.hProcess, 0))
{
DWORD err = ::GetLastError();
debugLog("d:\my_logs.txt", "Terminate err ", err);
}
}
return ERROR_SUCCESS;   
}
}
return -1;
}
int createProcess()
{
char *pcEnv = NULL;
char *pcEnvLan = NULL;
std::string commandLineStr;

pcEnv = getenv("GEHC_SECURITY_HOME");
si.cb = sizeof(si);
pcEnvLan = getenv("GEHC_SEC_LANG");
debugLog("d:\my_logs.txt",pcEnv);

if(pcEnv == NULL || pcEnvLan == NULL)
{
debugLog("d:\my_logs.txt", "Environment GEHC_SECURITY_HOME not set");
//g_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_SHUTDOWN;
g_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
g_ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
g_ServiceStatus.dwWin32ExitCode = 0;
g_ServiceStatus.dwCheckPoint = 4;

if(SetServiceStatus(g_StatusHandle, &g_ServiceStatus) == FALSE)
{
debugLog("d:\my_logs.txt", "Unable to set event in line ");
fclose(fp);
}
return -1;
}
std ::string str(pcEnv);
std :: string str1(pcEnvLan);


commandLineStr =
commandLineStr + "java -cp " + "\"" 
+ str.c_str()+ "\\eat\\jar\\eat.jar\";" + "\""
+ str.c_str()+ "\\my\\jar\\iungo.jar\";" + "\""
+ str.c_str()+ "\\my\\jar\\HDX.jar\";" +"\""
+ str.c_str()+ "\\my\\jar\\HDXser.jar\";" + "\""
+ str.c_str()+ "\\my\\jar\\antlr-runtime-3.1.jar\";" + "\""
+ str.c_str()+ "\\my\\jar\\jstyleparser-1.16-BSD.jar\";" + "\""
+ str.c_str()+ "\\my\\jar\\slf4j-api-1.7.5.jar\";" + "\""
+ str.c_str()+ "\\my\\jar\\slf4j-jdk14-1.7.5.jar\";" + "\""
+ str.c_str()+ "\\my\\jar\\my.jar\";" + "\""
+ str.c_str()+ "\\my\\jar\\commons-codec-1.9.jar\"" 
+ " -DGEHC_SECURITY_HOME=" + "\"" +str.c_str() + "\""
+ " -DGEHC_SEC_LANG=" + str1.c_str()
+" -Dterra.eat.model=CLIENT_SERVER com.ge.med.terra.eaaa.server.myServer %*";

char *pcStr = new char[commandLineStr.length() + 1];

strcpy(pcStr, commandLineStr.c_str());
debugLog("d:\my_logs.txt", pcStr);
int iRet = CreateProcess(NULL, // No module name (use command line)
(LPTSTR)pcStr, // Command line
NULL, // Process handle not inheritable
NULL, // Thread handle not inheritable
FALSE, // Set handle inheritance to FALSE
0, // No creation Flags
NULL, // Use parent's environment block
NULL, // Use parent's starting directory
&si, // Pointer to STARTUPINFO structure
&pi);
if(iRet == 0)
{
DWORD dw = GetLastError();
debugLog("d:\my_logs.txt","createfailed", dw);
delete[] pcStr;
return -1;
}
debugLog("d:\my_logs.txt", "Process started: ",pi.dwProcessId);
return 0;
}
VOID WINAPI ServiceMain1(DWORD argc, LPTSTR *argv)
{
DWORD Status = E_FAIL;

// Register our service control handler with the SCM
g_StatusHandle1 = RegisterServiceCtrlHandler(my1_SERVICE_NAME, ServiceCtrlHandler);
debugLog("d:\my_logs.txt", "In main1: ");
if(g_StatusHandle1 == NULL)
{
goto EXIT;
}

// Tell the service controller we are starting
ZeroMemory(&g_ServiceStatus1, sizeof(g_ServiceStatus1));
g_ServiceStatus1.dwServiceType = SERVICE_WIN32_SHARE_PROCESS ;
//g_ServiceStatus1.dwControlsAccepted = SERVICE_ACCEPT_SHUTDOWN;
g_ServiceStatus1.dwControlsAccepted = SERVICE_ACCEPT_STOP;
g_ServiceStatus1.dwCurrentState = SERVICE_START_PENDING;
g_ServiceStatus1.dwWin32ExitCode = 0;
g_ServiceStatus1.dwServiceSpecificExitCode = 0;
g_ServiceStatus1.dwCheckPoint = 0;

if(SetServiceStatus(g_StatusHandle1, &g_ServiceStatus1) == 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_ServiceStopEvent1 = CreateEvent(NULL, TRUE, FALSE, NULL);
if(g_ServiceStopEvent1 == NULL)
{
// Error creating event
// Tell service controller we are stopped and exit
g_ServiceStatus1.dwControlsAccepted = SERVICE_ACCEPT_SHUTDOWN;
g_ServiceStatus1.dwControlsAccepted = SERVICE_ACCEPT_STOP;
g_ServiceStatus1.dwCurrentState = SERVICE_STOPPED;
g_ServiceStatus1.dwWin32ExitCode = GetLastError();
g_ServiceStatus1.dwCheckPoint = 1;

if(SetServiceStatus(g_StatusHandle1, &g_ServiceStatus1) == FALSE)
{
OutputDebugString(
_T("My Sample Service: ServiceMain: SetServiceStatus returned error"));
}
goto EXIT;
}

// Tell the service controller we are started
//g_ServiceStatus1.dwControlsAccepted = SERVICE_ACCEPT_SHUTDOWN;
g_ServiceStatus1.dwControlsAccepted = SERVICE_ACCEPT_STOP;
g_ServiceStatus1.dwCurrentState = SERVICE_RUNNING;
g_ServiceStatus1.dwWin32ExitCode = 0;
g_ServiceStatus1.dwCheckPoint = 0;

if(SetServiceStatus(g_StatusHandle1, &g_ServiceStatus1) == FALSE)
{
OutputDebugString(
_T("My Sample Service: ServiceMain: SetServiceStatus returned error"));
}

// Start a thread that will perform the main task of the service
debugLog("d:\my1_logs.txt", "starting worker thread");
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_ServiceStopEvent1);

// Tell the service controller we are stopped
//g_ServiceStatus1.dwControlsAccepted = SERVICE_ACCEPT_SHUTDOWN;
g_ServiceStatus1.dwControlsAccepted = SERVICE_ACCEPT_STOP;
g_ServiceStatus1.dwCurrentState = SERVICE_STOPPED;
g_ServiceStatus1.dwWin32ExitCode = 0;
g_ServiceStatus1.dwCheckPoint = 3;

if(SetServiceStatus(g_StatusHandle1, &g_ServiceStatus1) == FALSE)
{
OutputDebugString(
_T("My Sample Service: ServiceMain: SetServiceStatus returned error"));
}

EXIT: return;
}

VOID WINAPI ServiceCtrlHandler1(DWORD CtrlCode)
{
debugLog("d:\my_logs.txt", "int ctrl1: ");
switch(CtrlCode)
{
case SERVICE_CONTROL_STOP:

if(g_ServiceStatus1.dwCurrentState != SERVICE_RUNNING)
break;

/*
* Perform tasks necessary to stop the service here
*/
//g_ServiceStatus1.dwControlsAccepted = SERVICE_ACCEPT_SHUTDOWN;
g_ServiceStatus1.dwControlsAccepted = SERVICE_ACCEPT_STOP;
g_ServiceStatus1.dwCurrentState = SERVICE_STOPPED;
g_ServiceStatus1.dwWin32ExitCode = 0;
g_ServiceStatus1.dwCheckPoint = 4;

if(SetServiceStatus(g_StatusHandle1, &g_ServiceStatus1) == FALSE)
{
debugLog("d:\my_logs.txt", "my1:Service Stop err");
}
// This will signal the worker thread to start shutting down
if(! SetEvent(g_ServiceStopEvent1))
{
debugLog("d:\my_logs.txt", "my1:Not Stopped Service ");
}
else
{
debugLog("d:\my_logs.txt", "my1: Stopped Service ");
}
break;
default:
break;
}
}
DWORD WINAPI ServiceWorkerThread1(LPVOID lpParam)
{
debugLog("d:\my_logs.txt", "in wrkr thrd1: ");
while(true)
{
if(0 == ismy1Started)
{
int iRet = createProcess();
ismy1Started = 1;
if(-1 == iRet)
{
debugLog("d:\my_logs.txt", "Create process failed!");
break;
}
}
HANDLE handles[2];
handles[0] = pi1.hProcess;
handles[1] = g_ServiceStopEvent1;
DWORD dwRet = WaitForMultipleObjects(2, handles, false, INFINITE);
if(WAIT_OBJECT_0 == dwRet)
{
debugLog("d:\my_logs.txt", "my server down");
ismy1Started = 0;
continue;
}
if(dwRet == WAIT_OBJECT_0 + 1)
{
//debugLog("d:\my_logs.txt", "Service stop received");
if(pi1.hProcess != NULL)
{
if(!TerminateProcess(pi1.hProcess, 0))
{
DWORD err = ::GetLastError();
debugLog("d:\my_logs.txt", "Terminate err ", err);
}
}
return ERROR_SUCCESS;
}
}
return -1;
}

int createProcess1()
{
char *pcEnv = NULL;
std::string commandLineStr;
pcEnv = getenv("GEHC_SECURITY_HOME");
si1.cb = sizeof(si1);

debugLog("d:\my_logs.txt",pcEnv);

if(pcEnv == NULL)
{
debugLog("d:\my_logs.txt", "Environment GEHC_SECURITY_HOME not set");
//g_ServiceStatus1.dwControlsAccepted = SERVICE_ACCEPT_SHUTDOWN;
g_ServiceStatus1.dwControlsAccepted = SERVICE_ACCEPT_STOP;
g_ServiceStatus1.dwCurrentState = SERVICE_STOP_PENDING;
g_ServiceStatus1.dwWin32ExitCode = 0;
g_ServiceStatus1.dwCheckPoint = 4;

if(SetServiceStatus(g_StatusHandle1, &g_ServiceStatus1) == FALSE)
{
debugLog("d:\my_logs.txt", "Unable to set event in line ");
fclose(fp);
}
return -1;
}
std::string str(pcEnv);
commandLineStr =
commandLineStr + "java -cp " + "\"" 
+ str.c_str()+ "/eat/jar/eat.jar\";" + "\""
+ str.c_str()+ "/eat/integration/eatsample.jar\";" + "\""
+ str.c_str()+"/eat/integration/eatTest.jar\";" +"\""
+ str.c_str()+ "/eat/3p/mail.jar\"" 
+ " -DGEHC_SECURITY_HOME=" + "/" +str.c_str() + "\""
+ " -DGEHC_SEC_LANG=%GEHC_SEC_LANG% -Dterra.eat.model=CLIENT_SERVER"
+ " com.ge.med.terra.eat.server.my1Server %*";
char *pcStr = new char[commandLineStr.length() + 1];
strcpy(pcStr, commandLineStr.c_str());
debugLog("d:\my_logs.txt", pcStr);

int iRet = CreateProcess( NULL, // No module name (use command line)
(LPTSTR)pcStr, // Command line
NULL, // Process handle not inheritable
NULL, // Thread handle not inheritable
FALSE, // Set handle inheritance to FALSE
0, // No creation Flags
NULL, // Use parent's environment block
NULL, // Use parent's starting directory
&si1, // Pointer to STARTUPINFO structure
&pi1);
if(iRet == 0)
{
return -1;
}
debugLog("d:\my_logs.txt", "Process started: ",pi1.dwProcessId);
return 0;
}

void debugLog(const char* fileName, const char *str, int value)
{
fp = fopen(fileName, "a");
fprintf(fp, "%s%i\n", str, value);
fclose(fp);
}

void debugLog(const char* fileName, const char *str)
{
fp = fopen(fileName, "a");
fputs(str, fp);
fputs("\n", fp);
fclose(fp);
}

int main()
{

SERVICE_TABLE_ENTRY ServiceTable[] = { { my_SERVICE_NAME,
(LPSERVICE_MAIN_FUNCTION) ServiceMain }, { my1_SERVICE_NAME,
(LPSERVICE_MAIN_FUNCTION) ServiceMain1 },{ NULL, NULL } };

if(StartServiceCtrlDispatcher(ServiceTable) == FALSE)
{
return GetLastError();
}

return 0;
}

0 个答案:

没有答案