Thanks I'll look into the priorities of the processes
Unfortunately the code is fairly long, since it has
to set up the service and all, but, here goes,
sample -d runs as a console app,
and the familiar sample -install and then
sample -start will run it as a service ...
here goes ....
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
SERVICE_STATUS status;
SERVICE_STATUS_HANDLE statusHandle;
DWORD err = 0;
TCHAR errstr[256];
BOOL dbg = FALSE;
VOID WINAPI serviceCtrl(DWORD dwCtrlCode);
VOID WINAPI serviceMain(DWORD dwArgc, LPTSTR *lpszArgv);
VOID CmdInstallService();
VOID CmdRemoveService();
VOID CmdStartService(int argc, char **argv);
VOID CmdStopService(int argc, char **argv);
void CmdDebugService(int argc, char ** argv);
BOOL WINAPI ControlHandler ( DWORD ctrl );
LPTSTR GetLastErrorText( LPTSTR lpszBuf, DWORD dwSize );
char reader_buf[1024];
char * SZSERVICENAME = "A Sample Service";
char * SZAPPNAME = "tst";
char * SZSERVICEDISPLAYNAME = "A Sample Service";
char * SZDEPENDENCIES = "";
/*
*
*/
int
appMain(int ac, char * av[])
{
time_t now = 0;
int n = 0, m = 0, j = 0;
FILE * fp = NULL;
HANDLE ph;
DWORD cl;
ph = GetCurrentProcess();
cl = GetPriorityClass(ph);
now = time(NULL);
for (n = 0; n < 100000; n++ ) {
for (m = 0; m < 10000; m++) {
j = m * n;
}
}
fp = fopen("c:/sample.log", "a+");
if (fp != NULL) {
fprintf(fp, "(%d) Run time : %d\n", cl, time(NULL) - now);
} else {
printf("(%d) Run time : %d\n", cl, time(NULL) - now);
}
return EXIT_SUCCESS;
}
/*
*
*/
int
appStop(void)
{
return 0;
}
/*
* Only auto start on a non-debug build, so that during
development
* a reboot will always stop a rogue service
*/
#if defined (DEBUG)
#define SERVICE_START_OPTION SERVICE_DEMAND_START
#else
#define SERVICE_START_OPTION SERVICE_AUTO_START
#endif
/*
* One argument
* -install registers the service with the
* Service Control Manager.
* -remove Removes the service from the
* Service Control Manager.
* -start Starts the service.
* -stop Stops the service.
*/
int
main(int argc, char **argv)
{
SERVICE_TABLE_ENTRY dispatchTable[] = {
{TEXT(SZSERVICENAME),
(LPSERVICE_MAIN_FUNCTION)serviceMain},
{NULL, NULL}
};
if ((argc > 1) && ((*argv[1] == '-'))) {
if (_stricmp("-install", argv[1]) == 0) {
CmdInstallService();
} else if (_stricmp( "-remove", argv[1]) == 0) {
CmdRemoveService();
} else if (_stricmp("-start", argv[1]) == 0) {
CmdStartService(argc, argv);
} else if (_stricmp("-stop", argv[1]) == 0) {
CmdStopService(argc, argv);
} else if (_stricmp("-d", argv[1]) == 0) {
dbg = TRUE;
CmdDebugService(argc, argv);
} else {
goto dispatch;
}
return 0;
}
dispatch:
/*
* Help message when the command is run from the console.
*/
printf( "%s -install to install the service\n",
SZAPPNAME );
printf( "%s -remove to remove the service\n",
SZAPPNAME );
printf( "%s -start to start the service\n", SZAPPNAME
);
printf( "%s -stop to stop the service\n", SZAPPNAME
);
printf( "\nStartServiceCtrlDispatcher being called.\n" );
printf( "This may take several seconds. Please wait.\n" );
StartServiceCtrlDispatcher(dispatchTable);
return 0;
}
/*
*
*/
void WINAPI
serviceMain(DWORD dwArgc, LPTSTR *lpszArgv)
{
/*
* Register service control handler
*/
statusHandle = RegisterServiceCtrlHandler(TEXT(SZSERVICENAME),
serviceCtrl);
if (!statusHandle)
goto finished;
/*
* Initialise SERVICE_STATUS
*/
status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
status.dwServiceSpecificExitCode = 0;
/*
* Status has to be reported to the SCM, since there is nothing
* else to do we go straight from pending to running
*/
if (!ReportStatusToSCMgr(SERVICE_START_PENDING, NO_ERROR, 3000))
goto finished;
if (!ReportStatusToSCMgr(SERVICE_RUNNING, NO_ERROR, 0))
goto finished;
appMain(dwArgc, lpszArgv);
finished:
/*
* Tell SCM service is stopping
*/
if (statusHandle)
(VOID)ReportStatusToSCMgr(SERVICE_STOPPED, err, 0);
}
/*
* This function is called by the SCM whenever
* ControlService() is called on this service.
*/
VOID WINAPI
serviceCtrl(DWORD dwCtrlCode)
{
switch(dwCtrlCode){
/*
* Stop the service.
*/
case SERVICE_CONTROL_STOP:
status.dwCurrentState = SERVICE_STOP_PENDING;
appStop();
break;
/*
* Update the service status.
*/
case SERVICE_CONTROL_INTERROGATE:
break;
}
ReportStatusToSCMgr(status.dwCurrentState, NO_ERROR, 0);
}
/*
* Sets the current status of the service and
* reports it to the Service Control Manager
*
* dwCurrentState - the state of the service
* dwWin32ExitCode - error code to report
* dwWaitHint - worst case estimate to next checkpoint
*/
BOOL
ReportStatusToSCMgr(DWORD dwCurrentState,
DWORD dwWin32ExitCode,
DWORD dwWaitHint)
{
static DWORD checkpoint = 1;
BOOL rc = TRUE;
if (dwCurrentState == SERVICE_START_PENDING)
status.dwControlsAccepted = 0;
else
status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
status.dwCurrentState = dwCurrentState;
status.dwWin32ExitCode = dwWin32ExitCode;
status.dwWaitHint = dwWaitHint;
if ((dwCurrentState == SERVICE_RUNNING) ||
(dwCurrentState == SERVICE_STOPPED))
status.dwCheckPoint = 0;
else
status.dwCheckPoint = checkpoint++;
/*
* Report the status of the service to the service
* control manager.
*/
rc = SetServiceStatus( statusHandle, &status);
return rc;
}
/*
*
*/
void
CmdInstallService()
{
SC_HANDLE srv;
SC_HANDLE svrmgr;
TCHAR path[512];
if ( GetModuleFileName( NULL, path, 512 ) == 0 ) {
printf(TEXT("Unable to install %s - %s\n"),
TEXT(SZSERVICEDISPLAYNAME),
GetLastErrorText(errstr, 256));
return;
}
printf("Install path is <%s>\n", path);
svrmgr = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (svrmgr) {
srv = CreateService(
svrmgr, // SCManager
database
TEXT(SZSERVICENAME), // name of service
TEXT(SZSERVICEDISPLAYNAME), // name to display
SERVICE_ALL_ACCESS, // desired access
SERVICE_WIN32_OWN_PROCESS, // service type
SERVICE_START_OPTION, // start type
SERVICE_ERROR_NORMAL, // error control
type
path, // service's binary
NULL, // no load ordering
group
NULL, // no tag identifier
TEXT(SZDEPENDENCIES), // dependencies
NULL, // LocalSystem
account
NULL); // no password
if ( srv ) {
printf(TEXT("%s installed.\n"),
TEXT(SZSERVICEDISPLAYNAME) );
CloseServiceHandle(srv);
} else {
printf(TEXT("CreateService fail - %s\n"),
GetLastErrorText(errstr, 256));
}
CloseServiceHandle(svrmgr);
} else
printf(TEXT("OpenSCManager fail - %s\n"),
GetLastErrorText(errstr,256));
}
/*
* Stops and removes the service
*/
void
CmdRemoveService()
{
SC_HANDLE srv;
SC_HANDLE svrmgr;
svrmgr = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (svrmgr) {
srv = OpenService(svrmgr, TEXT(SZSERVICENAME),
SERVICE_ALL_ACCESS);
if (srv) {
/*
* First make sure that the service is stopped.
*/
if (ControlService(srv, SERVICE_CONTROL_STOP, &status)) {
printf(TEXT("Stopping %s."),
TEXT(SZSERVICEDISPLAYNAME));
Sleep( 1000 );
while(QueryServiceStatus(srv, &status)) {
if (status.dwCurrentState == SERVICE_STOP_PENDING) {
printf(TEXT("."));
Sleep( 1000 );
} else {
break;
}
}
if (status.dwCurrentState == SERVICE_STOPPED)
printf(TEXT("\n%s stopped.\n"),
TEXT(SZSERVICEDISPLAYNAME));
else
printf(TEXT("\n%s failed to stop.\n"),
TEXT(SZSERVICEDISPLAYNAME));
}
/*
* Now remove the service
*/
if( DeleteService(srv) )
printf(TEXT("%s removed.\n"), TEXT(SZSERVICEDISPLAYNAME)
);
else
printf(TEXT("DeleteService fail - %s\n"),
GetLastErrorText(errstr,256));
CloseServiceHandle(srv);
} else {
printf(TEXT("OpenService fail - %s\n"),
GetLastErrorText(errstr,256));
}
CloseServiceHandle(svrmgr);
} else
printf(TEXT("OpenSCManager fail - %s\n"),
GetLastErrorText(errstr,256));
}
/*
* Starts the service.
*/
void
CmdStartService(int argc, char ** argv)
{
SC_HANDLE srv;
SC_HANDLE svrmgr;
svrmgr = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (svrmgr) {
srv = OpenService(svrmgr,
TEXT(SZSERVICENAME),
SERVICE_ALL_ACCESS);
if (srv) {
if(StartService(srv, 0, NULL)) {
printf(TEXT("Starting %s."),
TEXT(SZSERVICEDISPLAYNAME));
Sleep(1000);
while(QueryServiceStatus(srv, &status)) {
if (status.dwCurrentState ==
SERVICE_START_PENDING) {
printf(TEXT("."));
Sleep( 1000 );
} else {
break;
}
}
if (status.dwCurrentState == SERVICE_RUNNING)
printf(TEXT("\n%s started.\n"),
TEXT(SZSERVICEDISPLAYNAME));
else
printf(TEXT("\n%s failed to start.\n"),
TEXT(SZSERVICEDISPLAYNAME));
}
CloseServiceHandle(srv);
}else
printf(TEXT("OpenService fail - %s\n"),
GetLastErrorText(errstr,256));
CloseServiceHandle(svrmgr);
} else
printf(TEXT("OpenSCManager fail - %s\n"),
GetLastErrorText(errstr,256));
}
/*
* Stops the service.
*/
void
CmdStopService(int argc, char ** argv)
{
SC_HANDLE srv;
SC_HANDLE svrmgr;
svrmgr = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (svrmgr) {
srv = OpenService(svrmgr, TEXT(SZSERVICENAME),
SERVICE_ALL_ACCESS);
if (srv) {
/*
* First make sure that the service is stopped.
*/
if (ControlService(srv, SERVICE_CONTROL_STOP, &status)) {
printf(TEXT("Stopping %s."),
TEXT(SZSERVICEDISPLAYNAME));
Sleep( 1000 );
while(QueryServiceStatus(srv, &status)) {
if (status.dwCurrentState == SERVICE_STOP_PENDING) {
printf(TEXT("."));
Sleep( 1000 );
} else {
break;
}
}
if (status.dwCurrentState == SERVICE_STOPPED)
printf(TEXT("\n%s stopped.\n"),
TEXT(SZSERVICEDISPLAYNAME));
else
printf(TEXT("\n%s failed to stop.\n"),
TEXT(SZSERVICEDISPLAYNAME));
}
CloseServiceHandle(srv);
} else
printf(TEXT("OpenService fail - %s\n"),
GetLastErrorText(errstr,256));
CloseServiceHandle(svrmgr);
} else
printf(TEXT("OpenSCManager fail - %s\n"),
GetLastErrorText(errstr,256));
}
/*
* Debugging support function,
*
* Control C or control break will stop the
* service in debug mode.
*/
BOOL WINAPI
ControlHandler ( DWORD ctrl )
{
switch( ctrl ) {
case CTRL_BREAK_EVENT: // use Ctrl+C or Ctrl+Break to simulate
case CTRL_C_EVENT: // SERVICE_CONTROL_STOP in debug mode
printf(TEXT("Stopping %s.\n"), TEXT(SZSERVICEDISPLAYNAME));
appStop();
return TRUE;
}
return FALSE;
}
/*
* Debug support function, run the service as
* a consol mode application.
*
* argc - number of command line arguments
* argv - array of command line arguments
*/
void
CmdDebugService(int argc, char ** argv)
{
DWORD dwArgc;
LPTSTR *lpszArgv;
#ifdef UNICODE
lpszArgv = CommandLineToArgvW(GetCommandLineW(), &(dwArgc) );
#else
dwArgc = (DWORD) argc;
lpszArgv = argv;
#endif
printf(TEXT("Debugging %s.\n"), TEXT(SZSERVICEDISPLAYNAME));
SetConsoleCtrlHandler( ControlHandler, TRUE );
appMain( dwArgc, lpszArgv );
}
/*
* Copy text for error code into a string.
*/
LPTSTR
GetLastErrorText( LPTSTR lpszBuf, DWORD dwSize )
{
DWORD rc;
LPTSTR tmp = NULL;
rc = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_ARGUMENT_ARRAY,
NULL,
GetLastError(),
LANG_NEUTRAL,
(LPTSTR)&tmp,
0,
NULL);
/*
* A truncated message is worse than none at all, so return nothing
* if the whole message does not fit.
*/
if ( !rc || ( (long)dwSize < (long)rc+14 ) ) {
lpszBuf[0] = TEXT('\0');
} else {
int n = GetLastError();
/*
* Strip cr/lf
*/
tmp[lstrlen(tmp)-2] = TEXT('\0');
printf(lpszBuf, TEXT("%s (0x%x)"), tmp, n);
}
if ( tmp )
LocalFree((HLOCAL) tmp );
return lpszBuf;
}
*** Sent via Devdex
http://www.devdex.com ***
Don't just participate in USENET...get rewarded for it!