Page 1 of 1

create service not running

Posted: Sat Dec 20, 2014 5:36 am
by fafi
Please test..

Thank you..

Code: Select all

*******Service.prg**************

// A skeleton for writing a NT service for xHarbour compiler
// Author : Salvino Porto
// EMail : salvino.porto@gmail.com
// This file is derived from service.c by Craig Link - Microsoft Developer Support


// FUNCTION: Main
//
// PURPOSE: entrypoint for service
//
// PARAMETERS:
// cParameter - command line argument
//
// RETURN VALUE:
// none
//
// COMMENTS:


Function Main(cParameter)

if cParameter == NIL
cParameter:=""
end
if left(cParameter,1) != "-"
cParameter:=""
else
cParameter:=Upper(Substr(cParameter,2))
endif
Do Case
Case cParameter == "INSTALL"
CmdInstallService()
Case cParameter== "REMOVE"
CmdRemoveService()
Case cParameter == "HELP"
CmdHelp()
Case cParameter == "VERSION"
CmdVersion()
OtherWise
ServiceDispatch()
End Case

Return NIL

// FUNCTION: ExecuteService()
//
// PURPOSE: The main function of service action
//
// PARAMETERS:
// none
//
// RETURN VALUE:
// none
//
// COMMENTS:

Function ExecuteService()
do while IsServiceRunning()
Tone( 800, 1 )
SecondsSleep( 4 )
enddo
Return NIL


#pragma BEGINDUMP

#include <windows.h>
#include <tchar.h>
#include <hbapi.h>
#include <hbvm.h>

//#include "service.ch"

//**********************service.ch****************** ****
#define SZSERVICENAME "FirstxHarbourService"
#define SZVERSION "1.0"
#define SZSERVICEDISPLAYNAME "My first xHarbour Service"
#define SZAPPNAME "service"
#define SZDEPENDENCIES ""


// internal variables
SERVICE_STATUS ssStatus; // current status of the service
SERVICE_STATUS_HANDLE sshStatusHandle;
DWORD dwErr = 0;
TCHAR szErr[256];

HANDLE hServerStopEvent = NULL;
static PHB_DYNS s_pDynExecuteService;


// internal function prototypes
VOID WINAPI service_ctrl(DWORD dwCtrlCode);
VOID WINAPI service_main(void);
void ServiceStop(void);
void ServiceStart(void);
void ServiceExecutionThread(void);
BOOL ReportStatusToSCMgr(DWORD , DWORD , DWORD );
VOID AddToMessageLog(LPTSTR);
LPTSTR GetLastErrorText( LPTSTR , DWORD );

// FUNCTION: IsServiceRunning
//
// PURPOSE: Notify to xHarbour code if service is running
//
// PARAMETERS:
// none
//
// RETURN VALUE:
// none
//
// COMMENTS:
HB_FUNC ( ISSERVICERUNNING )
{
hb_retl(ssStatus.dwCurrentState == SERVICE_RUNNING);
}

// FUNCTION: ServiceDispatch
//
// PURPOSE: entrypoint for C code
//
// PARAMETERS:
// none
//
// RETURN VALUE:
// none
//
// COMMENTS:
HB_FUNC_STATIC ( SERVICEDISPATCH )
{

SERVICE_TABLE_ENTRY dispatchTable[] =
{
{ TEXT(SZSERVICENAME), (LPSERVICE_MAIN_FUNCTION)service_main },
{ NULL, NULL }
};
if (!StartServiceCtrlDispatcher(dispatchTable))
AddToMessageLog(TEXT("StartServiceCtrlDispatcher failed."));
}

// FUNCTION: service_main
//
// PURPOSE: To perform actual initialization of the service
//
// PARAMETERS:
// dwArgc - number of command line arguments
// lpszArgv - array of command line arguments
//
// RETURN VALUE:
// none
//
// COMMENTS:
// This routine performs the service initialization and then calls
// the user defined ServiceStart() routine to perform majority
// of the work.

void WINAPI service_main(void)
{
// register our service control handler:
sshStatusHandle = RegisterServiceCtrlHandler( TEXT(SZSERVICENAME),
service_ctrl);

if (!sshStatusHandle)
return;

// SERVICE_STATUS members that don't change in example
ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
ssStatus.dwServiceSpecificExitCode = 0;

// report the status to the service control manager.
if (ReportStatusToSCMgr(
(DWORD)SERVICE_START_PENDING, // service state
NO_ERROR, // exit code
(DWORD)3000)) // wait hint

// Start up the service
ServiceStart();

// try to report the stopped status to the service control manager.
if (sshStatusHandle)
ReportStatusToSCMgr((DWORD)SERVICE_STOPPED, dwErr, (DWORD)0);

return;
} // service_main


// FUNCTION: service_ctrl
//
// PURPOSE: This function is called by the SCM whenever
// ControlService() is called on this service.
//
// PARAMETERS:
// dwCtrlCode - type of control requested
//
// RETURN VALUE:
// none
//
// COMMENTS:

VOID WINAPI service_ctrl(DWORD dwCtrlCode)
{
// Handle the requested control code.
switch(dwCtrlCode)
{
// Stop the service.
case SERVICE_CONTROL_STOP:
ssStatus.dwCurrentState = SERVICE_STOP_PENDING;
ServiceStop();
break;

// Update the service status.
case SERVICE_CONTROL_INTERROGATE:
break;

// invalid control code
default:
break;
}
ReportStatusToSCMgr(ssStatus.dwCurrentState, NO_ERROR, (DWORD)0);
} // service_ctrl


// FUNCTION: ServiceStart
//
// PURPOSE: Actual code of the service that does the work.
//
// PARAMETERS:
// dwArgc - number of command line arguments
// lpszArgv - array of command line arguments
//
// RETURN VALUE:
// none
//
// COMMENTS:
// The service stops when hServerStopEvent is signalled
void ServiceStart (void)
{
DWORD idThread;

// Service initialization

// report the status to the service control manager.
if (!ReportStatusToSCMgr(SERVICE_START_PENDING, NO_ERROR, 3000))
return;

// create the event object. The control handler function signals
// this event when it receives the "stop" control code.
if((hServerStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL)) == NULL)
return;

// report the status to the service control manager.
if (!ReportStatusToSCMgr(SERVICE_START_PENDING, NO_ERROR, 3000))
goto cleanup;

// report the status to the service control manager.
if (!ReportStatusToSCMgr(SERVICE_START_PENDING, NO_ERROR, 3000))
goto cleanup;

// create the working thread
if ( CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE)ServiceExecutionThread, 0, 0, &idThread)==NULL)
goto cleanup;
// report the status to the service control manager.
if (!ReportStatusToSCMgr(SERVICE_RUNNING, NO_ERROR, 3000))
goto cleanup;

// End of initialization

_tprintf(TEXT("Init %s ok.\n"), TEXT(SZSERVICEDISPLAYNAME));

// Service is now running, perform work until shutdown
WaitForSingleObject(hServerStopEvent,INFINITE);
CloseHandle(hServerStopEvent);

cleanup:

if (hServerStopEvent)
CloseHandle(hServerStopEvent);
}


//
// FUNCTION: ServiceStop
//
// PURPOSE: Stops the service
//
// PARAMETERS:
// none
//
// RETURN VALUE:
// none
//
// COMMENTS:
// If a ServiceStop procedure is going to
// take longer than 3 seconds to execute,
// it should spawn a thread to execute the
// stop code, and return. Otherwise, the
// ServiceControlManager will believe that
// the service has stopped responding.
//
void ServiceStop()
{
if ( hServerStopEvent )
SetEvent(hServerStopEvent);
}

// FUNCTION: ServiceExecutionThread
//
// PURPOSE: Invoke the xHarbour ExecuteService procedure
//
// PARAMETERS:
// none
//
// RETURN VALUE:
// none
//
// COMMENTS:

void ServiceExecutionThread(void)
{
s_pDynExecuteService = hb_dynsymGet( "ExecuteService" );

if( s_pDynExecuteService != NULL )
{
hb_vmPushSymbol( s_pDynExecuteService->pSymbol );
hb_vmPushNil();
hb_vmDo( 0 );
}
return;

}


// FUNCTION: ReportStatusToSCMgr()
//
// PURPOSE: Sets the current status of the service and
// reports it to the Service Control Manager
//
// PARAMETERS:
// dwCurrentState - the state of the service
// dwWin32ExitCode - error code to report
// dwWaitHint - worst case estimate to next checkpoint
//
// RETURN VALUE:
// TRUE - success
// FALSE - failure
//
// COMMENTS:

BOOL ReportStatusToSCMgr(DWORD dwCurrentState,
DWORD dwWin32ExitCode,
DWORD dwWaitHint)
{
static DWORD dwCheckPoint = 1;
BOOL fResult;

if (dwCurrentState == SERVICE_START_PENDING)
ssStatus.dwControlsAccepted = 0;
else
ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;

ssStatus.dwCurrentState = dwCurrentState;
ssStatus.dwWin32ExitCode = dwWin32ExitCode;
ssStatus.dwWaitHint = dwWaitHint;

if ( ( dwCurrentState == SERVICE_RUNNING ) ||
( dwCurrentState == SERVICE_STOPPED ) )
ssStatus.dwCheckPoint = 0;
else
ssStatus.dwCheckPoint = dwCheckPoint++;


// Report the status of the service to the service control manager.
//
fResult = SetServiceStatus( sshStatusHandle, &ssStatus);
if (!fResult)
AddToMessageLog(TEXT("SetServiceStatus"));

return fResult;
} // ReportStatusToSCMg


// FUNCTION: AddToMessageLog(LPTSTR lpszMsg)
//
// PURPOSE: Allows any thread to log an error message
//
// PARAMETERS:
// lpszMsg - text for message
//
// RETURN VALUE:
// none
//
// COMMENTS:

VOID AddToMessageLog(LPTSTR lpszMsg)
{
TCHAR szMsg[256];
HANDLE hEventSource;
LPTSTR lpszStrings[2];

dwErr = GetLastError();

// Use event logging to log the error.
//
hEventSource = RegisterEventSource(NULL, TEXT(SZSERVICENAME));

_stprintf(szMsg, TEXT("%s error: %d"), TEXT(SZSERVICENAME), dwErr);
lpszStrings[0] = szMsg;
lpszStrings[1] = lpszMsg;

if (hEventSource != NULL) {
ReportEvent(hEventSource, // handle of event source
EVENTLOG_ERROR_TYPE, // event type
0, // event category
0, // event ID
NULL, // current user's SID
2, // strings in lpszStrings
0, // no bytes of raw data
(LPCTSTR *)lpszStrings, // array of error strings
NULL); // no raw data

(VOID) DeregisterEventSource(hEventSource);
}
} // AddToMessageLog



// The following code handles service installation and removal


// FUNCTION: CmdInstallService()
//
// PURPOSE: Installs the service
//
// PARAMETERS:
// none
//
// RETURN VALUE:
// none
//
// COMMENTS:

HB_FUNC_STATIC ( CMDINSTALLSERVICE )
{
SC_HANDLE schService;
SC_HANDLE schSCManager;

TCHAR szPath[512];

if ( GetModuleFileName( NULL, szPath, 512 ) == 0 )
{
_tprintf(TEXT("Unable to install %s - %s\n"),
TEXT(SZSERVICEDISPLAYNAME), GetLastErrorText(szErr, 256));
return;
}

schSCManager = OpenSCManager(
NULL, // machine (NULL == local)
NULL, // database (NULL == default)
SC_MANAGER_ALL_ACCESS // access required
);
if ( schSCManager )
{
schService = CreateService(
schSCManager, // SCManager database
TEXT(SZSERVICENAME), // name of service
TEXT(SZSERVICEDISPLAYNAME), // name to display
SERVICE_ALL_ACCESS, // desired access
SERVICE_WIN32_OWN_PROCESS, // service type
SERVICE_AUTO_START, // start type
SERVICE_ERROR_NORMAL, // error control type
szPath, // service's binary
NULL, // no load ordering group
NULL, // no tag identifier
TEXT(SZDEPENDENCIES), // dependencies
NULL, // LocalSystem account
NULL); // no password

if ( schService )
{
_tprintf(TEXT("%s installed.\n"), TEXT(SZSERVICEDISPLAYNAME) );
StartService(schService,0,NULL);
_tprintf(TEXT("%s starting....\n"),
TEXT(SZSERVICEDISPLAYNAME) );
CloseServiceHandle(schService);
}
else
{
_tprintf(TEXT("CreateService failed - %s\n"),
GetLastErrorText(szErr, 256));
}

CloseServiceHandle(schSCManager);
}
else
_tprintf(TEXT("OpenSCManager failed - %s\n"),
GetLastErrorText(szErr,256));
}


// FUNCTION: CmdRemoveService()
//
// PURPOSE: Stops and removes the service
//
// PARAMETERS:
// none
//
// RETURN VALUE:
// none
//
// COMMENTS:

HB_FUNC_STATIC ( CMDREMOVESERVICE )
{
SC_HANDLE schService;
SC_HANDLE schSCManager;

schSCManager = OpenSCManager(
NULL, // machine (NULL == local)
NULL, // database (NULL == default)
SC_MANAGER_ALL_ACCESS // access required
);
if ( schSCManager )
{
schService = OpenService(schSCManager, TEXT(SZSERVICENAME),
SERVICE_ALL_ACCESS);

if (schService)
{
// try to stop the service
if ( ControlService( schService, SERVICE_CONTROL_STOP,
&ssStatus ) )
{
_tprintf(TEXT("Stopping %s."), TEXT(SZSERVICEDISPLAYNAME));
Sleep( 1000 );

while( QueryServiceStatus( schService, &ssStatus ) )
{
if ( ssStatus.dwCurrentState == SERVICE_STOP_PENDING )
{
_tprintf(TEXT("."));
Sleep( 1000 );
}
else
break;
}

if ( ssStatus.dwCurrentState == SERVICE_STOPPED )
_tprintf(TEXT("\n%s stopped.\n"),
TEXT(SZSERVICEDISPLAYNAME) );
else
_tprintf(TEXT("\n%s failed to stop.\n"),
TEXT(SZSERVICEDISPLAYNAME) );

}

// now remove the service
if( DeleteService(schService) )
_tprintf(TEXT("%s removed.\n"),
TEXT(SZSERVICEDISPLAYNAME) );
else
_tprintf(TEXT("DeleteService failed - %s\n"),
GetLastErrorText(szErr,256));


CloseServiceHandle(schService);
}
else
_tprintf(TEXT("OpenService failed - %s\n"),
GetLastErrorText(szErr,256));

CloseServiceHandle(schSCManager);
}
else
_tprintf(TEXT("OpenSCManager failed - %s\n"),
GetLastErrorText(szErr,256));
}

// FUNCTION: CmdHelp()
//
// PURPOSE: Displays help information
//
// PARAMETERS:
// none
//
// RETURN VALUE:
// none
//
// COMMENTS:

HB_FUNC_STATIC ( CMDHELP )
{
printf("%s -install to install the service\n", SZAPPNAME);
printf("%s -remove to remove the service\n", SZAPPNAME);
printf("%s -help to display this help screen\n",SZAPPNAME);
printf("%s -version to print the version of the service\n",SZAPPNAME);
} // CmdHelp

// FUNCTION: CmdVersion()
//
// PURPOSE: Displays version information
//
// PARAMETERS:
// none
//
// RETURN VALUE:
// none
//
// COMMENTS:

HB_FUNC_STATIC ( CMDVERSION )
{
printf("%s version %s\n", SZAPPNAME, SZVERSION);
} // CmdVersion

// FUNCTION: GetLastErrorText
//
// PURPOSE: copies error message text to string
//
// PARAMETERS:
// lpszBuf - destination buffer
// dwSize - size of buffer
//
// RETURN VALUE:
// destination buffer
//
// COMMENTS:

LPTSTR GetLastErrorText( LPTSTR lpszBuf, DWORD dwSize )
{
DWORD dwRet;
LPTSTR lpszTemp = NULL;

dwRet = FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER
|FORMAT_MESSAGE_FROM_SYSTEM |FORMAT_MESSAGE_ARGUMENT_ARRAY,
NULL,
GetLastError(),
LANG_NEUTRAL,
(LPTSTR)&lpszTemp,
0,
NULL );

// supplied buffer is not long enough
if ( !dwRet || ( (long)dwSize < (long)dwRet+14 ) )
lpszBuf[0] = TEXT('\0');
else
{
lpszTemp[lstrlen(lpszTemp)-2] = TEXT('\0'); //remove cr and newline character
_stprintf( lpszBuf, TEXT("%s (0x%x)"), lpszTemp, GetLastError() );
}

if ( lpszTemp )
LocalFree((HLOCAL) lpszTemp );

return lpszBuf;
} // GetLastErrorText


#pragma ENDDUMP
 
Best regards
Fafi