Solved

Windows Service Not Working

Posted on 2003-10-28
12
5,903 Views
Last Modified: 2008-02-01
I am trying to create a windows service.  But it is not doing what it is supposed to and it will not stop.  Please help!

Here is My Code.
#################
Simple.Cpp
#################

//----------------------------------------------------------------------
#include <string>
#include <fstream>
#include <direct.h>
#include <io.h>
#include <time.h>
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <process.h>
#include <tchar.h>
#include "service.h"

using namespace std;

//----------------------------------------------------------------------
void GrabVariables(char [], char [], char[], int&, char [], char[]);

void Process1Interval(int, char [], char[], char[], char[], char[]);

void SleepForInterval(int);

int CheckSettings(char [], char [], int&, char []);

void MoveOptionFile(char[], char[]);

DWORD ExecuteAsyncHidden(LPSTR   pszCmd, char []);

void LogErrors(char [], char[]);

//----------------------------------------------------------------------

HANDLE  hServerStopEvent = NULL;

//----------------------------------------------------------------------
VOID ServiceStart (DWORD dwArgc, LPTSTR *lpszArgv)
{


      char djEnginePath[200];
      int pollingInterval=0;
      char errorLog[30];
      char fThread[10];
      char archivedPath[200];
      char optionFilePath[200];

            while ( 1 )
            {


            GrabVariables(errorLog,optionFilePath, djEnginePath, pollingInterval, fThread, archivedPath);
      
                  if(CheckSettings(djEnginePath, optionFilePath, pollingInterval, errorLog) == 0)
                  {       
                  Process1Interval(pollingInterval,optionFilePath,fThread, archivedPath, errorLog,djEnginePath);
                  SleepForInterval(pollingInterval);
                  } else {
                  SleepForInterval(pollingInterval);
                  }
            }



}
//----------------------------------------------------------------------

VOID ServiceStop()
{
    if ( hServerStopEvent )
        SetEvent(hServerStopEvent);
}

//----------------------------------------------------------------------
//----------------------------------------------------------------------
void GrabVariables(char errorLog[], char optionFilePath[],char djEnginePath[], int &pollingInterval, char fThread[], char archivedPath[])
{
char path[30];
char temp[5];
strcpy(path,getenv("windir"));
strcat(path,"\\processsettings");

strcpy(errorLog,getenv("windir"));
strcat(errorLog,"\\error.log");

ifstream filein(path, ios::in);

      if(!filein.fail())
      {
      filein.getline(optionFilePath,200,'\n');
      filein.getline(djEnginePath,200,'\n');
      filein.getline(temp,5,'\n');
      
      pollingInterval = atoi(temp);

      filein.getline(fThread,10,'\n');
      filein.close();
      } else {
       LogErrors(errorLog,"ERROR: EWaitress Settings Could Not Be Opened");
       SleepForInterval(60);
      }

strcpy(archivedPath,optionFilePath);
strcat(archivedPath,"\\Archived");

}
//----------------------------------------------------------------------
void Process1Interval(int pollingInterval,char optionFilePath[], char fThread[], char archivedPath[], char errorLog[], char djEnginePath[])
{
char fileName[30];

HANDLE findfile;
WIN32_FIND_DATA finddata;

if (access(optionFilePath, 0) != -1)
{
SetCurrentDirectory(optionFilePath);

char engine[100];
char command[300];

strcpy(engine,djEnginePath);
strcat(engine, "\\djengine.exe @ \"");

findfile = FindFirstFile("*.*",&finddata);
    while(FindNextFile(findfile,&finddata))
    {
       if((finddata.dwFileAttributes!=FILE_ATTRIBUTE_DIRECTORY) && (strcmp(finddata.cFileName,"..")!=0) && (strcmp(finddata.cFileName,".")!=0))
       {
                  strcpy(fileName,finddata.cFileName);
                  
                        strcpy(command,engine);
                        strcat(command, optionFilePath);
                        strcat(command, "\\");
                        strcat(command,fileName);
                        strcat(command, "\"");
                  
                        SetCurrentDirectory(djEnginePath);

                        ExecuteAsyncHidden(command,fThread);
                        
                        if(strcmp(fThread,"multi") == 0 )
                        Sleep(3000);

                        SetCurrentDirectory(optionFilePath);
            
                        MoveOptionFile(archivedPath, fileName);
       }
    }
      FindClose ( findfile);
}
}
//----------------------------------------------------------------------
void SleepForInterval(int pollingInterval)
{
      Sleep(pollingInterval * 1000);
}
//----------------------------------------------------------------------
int CheckSettings(char djEnginePath[], char optionFilePath[], int& pollingInterval, char errorLog[])
{
      int invalidSettings = 0;
      char path[300];

      //Check Data Junction Path
      if (access(djEnginePath, 0) == -1)
      {
      LogErrors(errorLog,"ERROR: Data Junction File Path Does Not Exist");
      invalidSettings = 1;
      } else {
      //check for djengine.exe
      strcpy(path, djEnginePath);
      strcat(path,"\\djengine.exe");

            if (0xffffffff == GetFileAttributes(path))
            {
            LogErrors(errorLog,"ERROR: Data Junction Executable \"djengine.exe\" Does Not Exist");
            invalidSettings = 1;
            }
      }

      //Check OptionFile Path
      if (access(optionFilePath, 0) == -1)
      {
            LogErrors(errorLog,"ERROR: Option File Path Does Not Exist");
            invalidSettings = 1;
      }

      //Check PollingInterval
      if(pollingInterval < 5 || pollingInterval > 3600)
      {
            LogErrors(errorLog,"WARNING: Polling Interval is out of Range - Now Set to 60 seconds");
            pollingInterval = 60;
      }
      
      return invalidSettings;
}
//----------------------------------------------------------------------
void MoveOptionFile(char archivedPath[], char fileName[])
{
char newPath[200];
char command[250];

char time_buffer[40] = {0};
time_t now = time(NULL);
struct tm *localtm = localtime(&now);
strftime(time_buffer, 40, "%m.%d.%Y", localtm);


if (access(archivedPath, 0) == -1)
    _mkdir(archivedPath);

strcpy(newPath,archivedPath);
strcat(newPath,"\\");
strcat(newPath,time_buffer);

if (access(newPath, 0) == -1)
    _mkdir(newPath);

strcat(newPath,"\\");
strcat(newPath,fileName);

strcpy(command,"move \"");
strcat(command, fileName);
strcat(command,"\" \"");
strcat(command, newPath);
strcat(command, "\" ");

system(command);
}
//----------------------------------------------------------------------

DWORD ExecuteAsyncHidden   (LPSTR   pszCmd, char fThread[])
{
   STARTUPINFO         si;
   PROCESS_INFORMATION pi;

   BOOL                bRes;

   DWORD               dwCode  =   0;

   ZeroMemory  (   &si,    sizeof  (   STARTUPINFO));

   si.cb           =   sizeof  (   STARTUPINFO);
   si.dwFlags      =   STARTF_USESHOWWINDOW;
   si.wShowWindow  =   SW_HIDE;

   bRes    =   CreateProcess   (   NULL,
                                   pszCmd,
                                   NULL,
                                   NULL,
                                   TRUE,
                                   NORMAL_PRIORITY_CLASS,
                                   NULL,
                                   NULL,
                                   &si,
                                   &pi
                               );

   if(strcmp(fThread,"single") == 0 )
   WaitForSingleObject(pi.hProcess,INFINITE);

   CloseHandle (   pi.hProcess);
   CloseHandle (   pi.hThread);

   return  (dwCode);
}
//----------------------------------------------------------------------
void LogErrors(char errorLog[], char error[])
{
      ofstream fileout(errorLog, ios::out | ios::app);

      fileout << error << endl;

      fileout.close();
}
//----------------------------------------------------------------------


#################
Service.C
#################

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <process.h>
#include <tchar.h>

#include "service.h"



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

// internal function prototypes
VOID WINAPI service_ctrl(DWORD dwCtrlCode);
VOID WINAPI service_main(DWORD dwArgc, LPTSTR *lpszArgv);
VOID CmdInstallService();
VOID CmdRemoveService();
VOID CmdDebugService(int argc, char **argv);
BOOL WINAPI ControlHandler ( DWORD dwCtrlType );
LPTSTR GetLastErrorText( LPTSTR lpszBuf, DWORD dwSize );

//
//  FUNCTION: main
//
//  PURPOSE: entrypoint for service
//
//  PARAMETERS:
//    argc - number of command line arguments
//    argv - array of command line arguments
//
//  RETURN VALUE:
//    none
//
//  COMMENTS:
//    main() either performs the command line task, or
//    call StartServiceCtrlDispatcher to register the
//    main service thread.  When the this call returns,
//    the service has stopped, so exit.
//
void _CRTAPI1 main(int argc, char **argv)
{
    SERVICE_TABLE_ENTRY dispatchTable[] =
    {
        { TEXT(SZSERVICENAME), (LPSERVICE_MAIN_FUNCTION)service_main },
        { NULL, NULL }
    };

    if ( (argc > 1) &&
         ((*argv[1] == '-') || (*argv[1] == '/')) )
    {
        if ( _stricmp( "install", argv[1]+1 ) == 0 )
        {
            CmdInstallService();
        }
        else if ( _stricmp( "remove", argv[1]+1 ) == 0 )
        {
            CmdRemoveService();
        }
        else if ( _stricmp( "debug", argv[1]+1 ) == 0 )
        {
            bDebug = TRUE;
            CmdDebugService(argc, argv);
        }
        else
        {
            goto dispatch;
        }
        exit(0);
    }

    // if it doesn't match any of the above parameters
    // the service control manager may be starting the service
    // so we must call StartServiceCtrlDispatcher
    dispatch:
        // this is just to be friendly
        printf( "%s -install          to install the service\n", SZAPPNAME );
        printf( "%s -remove           to remove the service\n", SZAPPNAME );
        printf( "%s -debug <params>   to run as a console app for debugging\n", SZAPPNAME );
        printf( "\nStartServiceCtrlDispatcher being called.\n" );
        printf( "This may take several seconds.  Please wait.\n" );

        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(DWORD dwArgc, LPTSTR *lpszArgv)
{

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

    if (!sshStatusHandle)
        goto cleanup;

    // 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(
        SERVICE_START_PENDING, // service state
        NO_ERROR,              // exit code
        3000))                 // wait hint
        goto cleanup;


    ServiceStart( dwArgc, lpszArgv );

cleanup:

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

    return;
}



//
//  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.
        //
        // SERVICE_STOP_PENDING should be reported before
        // setting the Stop Event - hServerStopEvent - in
        // ServiceStop().  This avoids a race condition
        // which may result in a 1053 - The Service did not respond...
        // error.
        case SERVICE_CONTROL_STOP:
            ReportStatusToSCMgr(SERVICE_STOP_PENDING, NO_ERROR, 0);
            ServiceStop();
            return;

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

        // invalid control code
        //
        default:
            break;

    }

    ReportStatusToSCMgr(ssStatus.dwCurrentState, NO_ERROR, 0);
}



//
//  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 = TRUE;


    if ( !bDebug ) // when debugging we don't report to the SCM
    {
        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.
        //
        if (!(fResult = SetServiceStatus( sshStatusHandle, &ssStatus))) {
            AddToMessageLog(TEXT("SetServiceStatus"));
        }
    }
    return fResult;
}



//
//  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];


    if ( !bDebug )
    {
        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
                lpszStrings,          // array of error strings
                NULL);                // no raw data

            (VOID) DeregisterEventSource(hEventSource);
        }
    }
}




///////////////////////////////////////////////////////////////////
//
//  The following code handles service installation and removal
//


//
//  FUNCTION: CmdInstallService()
//
//  PURPOSE: Installs the service
//
//  PARAMETERS:
//    none
//
//  RETURN VALUE:
//    none
//
//  COMMENTS:
//
void 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_DEMAND_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) );
            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:
//
void 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));
}




///////////////////////////////////////////////////////////////////
//
//  The following code is for running the service as a console app
//


//
//  FUNCTION: CmdDebugService(int argc, char ** argv)
//
//  PURPOSE: Runs the service as a console application
//
//  PARAMETERS:
//    argc - number of command line arguments
//    argv - array of command line arguments
//
//  RETURN VALUE:
//    none
//
//  COMMENTS:
//
void CmdDebugService(int argc, char ** argv)
{
    DWORD dwArgc;
    LPTSTR *lpszArgv;

#ifdef UNICODE
    lpszArgv = CommandLineToArgvW(GetCommandLineW(), &(dwArgc) );
#else
    dwArgc   = (DWORD) argc;
    lpszArgv = argv;
#endif

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

    SetConsoleCtrlHandler( ControlHandler, TRUE );

    ServiceStart( dwArgc, lpszArgv );
}


//
//  FUNCTION: ControlHandler ( DWORD dwCtrlType )
//
//  PURPOSE: Handled console control events
//
//  PARAMETERS:
//    dwCtrlType - type of control event
//
//  RETURN VALUE:
//    True - handled
//    False - unhandled
//
//  COMMENTS:
//
BOOL WINAPI ControlHandler ( DWORD dwCtrlType )
{
    switch( dwCtrlType )
    {
        case CTRL_BREAK_EVENT:  // use Ctrl+C or Ctrl+Break to simulate
        case CTRL_C_EVENT:      // SERVICE_CONTROL_STOP in debug mode
            _tprintf(TEXT("Stopping %s.\n"), TEXT(SZSERVICEDISPLAYNAME));
            ServiceStop();
            return TRUE;
            break;

    }
    return FALSE;
}

//
//  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;
}

########################
Service.h
########################

#ifndef _SERVICE_H
#define _SERVICE_H


#ifdef __cplusplus
extern "C" {
#endif


//////////////////////////////////////////////////////////////////////////////
//// todo: change to desired strings
////
// name of the executable
#define SZAPPNAME            "EWaitress"
// internal name of the service
#define SZSERVICENAME        "EWaitressService"
// displayed name of the service
#define SZSERVICEDISPLAYNAME "EWaitress Service"
// list of service dependencies - "dep1\0dep2\0\0"
#define SZDEPENDENCIES       ""
//////////////////////////////////////////////////////////////////////////////



//////////////////////////////////////////////////////////////////////////////
//// todo: ServiceStart()must be defined by in your code.
////       The service should use ReportStatusToSCMgr to indicate
////       progress.  This routine must also be used by StartService()
////       to report to the SCM when the service is running.
////
////       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 ServiceStart(DWORD dwArgc, LPTSTR *lpszArgv);
VOID ServiceStop();
//////////////////////////////////////////////////////////////////////////////



//////////////////////////////////////////////////////////////////////////////
//// The following are procedures which
//// may be useful to call within the above procedures,
//// but require no implementation by the user.
//// They are implemented in service.c

//
//  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
//
BOOL ReportStatusToSCMgr(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint);


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


#ifdef __cplusplus
}
#endif

#endif

0
Comment
Question by:RowdyOne078
  • 6
  • 6
12 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 9636053
Regarding the 'not stopping' issue - you are not waiting for hStopEvent anywhere in your code and are not initializing it by calling 'CreateEvent()'. BTW, the file you are reading your variables from should reside in "system32", this is the working directory for services.
0
 

Author Comment

by:RowdyOne078
ID: 9636070
I just realized that the service is "stuck" with Service Start Pending
0
 
LVL 86

Expert Comment

by:jkr
ID: 9636121
Add, I see - you have to inform the SCM that your service has finished its initialization by calling

ReportStatusToSCMgr(
       SERVICE_RUNNING, // service state
       NO_ERROR,              // exit code
       0);

in your 'StartService()' function.      
0
 

Author Comment

by:RowdyOne078
ID: 9636415
Can you help me more with this?  I dont know what I need to do.


Regarding the 'not stopping' issue - you are not waiting for hStopEvent anywhere in your code and are not initializing it by calling 'CreateEvent()'.
0
 
LVL 86

Accepted Solution

by:
jkr earned 500 total points
ID: 9636473
You need to set up your event, e.g. like

hStopEvent = CreateEvent ( NULL, FALSE, TRUE, NULL);

Then, you need to check the state of your event:

if ( WAIT_TIMEOUT != WaitForSingleObject ( hEvent, 1000)) { // hey, we could use this for 'sleeping' :o)

   return; // exit from function if event was set
}

Put this in your 'ServiceMain()':

VOID ServiceStart (DWORD dwArgc, LPTSTR *lpszArgv)
{
    hStopEvent = CreateEvent ( NULL, FALSE, TRUE, NULL);

    char djEnginePath[200];
    int pollingInterval=0;
    char errorLog[30];
    char fThread[10];
    char archivedPath[200];
    char optionFilePath[200];

         while ( 1 )
         {


         GrabVariables(errorLog,optionFilePath, djEnginePath, pollingInterval, fThread, archivedPath);
   
               if(CheckSettings(djEnginePath, optionFilePath, pollingInterval, errorLog) == 0)
              {      
               Process1Interval(pollingInterval,optionFilePath,fThread, archivedPath, errorLog,djEnginePath);
              }

               if ( WAIT_TIMEOUT != WaitForSingleObject ( hStopEvent, pollingInterval * 1000)) { // hey, we could use this for 'sleeping' :o)

                 return; // exit from function if event was set
               }
         }
}
0
 

Author Comment

by:RowdyOne078
ID: 9636884
OK its getting closer...  If I use the above code, it stops the service the first loop everytime.

Thanks.
Greg
0
Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

 
LVL 86

Expert Comment

by:jkr
ID: 9636902
>>it stops the service the first loop everytime

My fault :o)

Use

hStopEvent = CreateEvent ( NULL, FALSE, FALSE, NULL);

and it should work.
0
 

Author Comment

by:RowdyOne078
ID: 9637626
JKR you are the MAN!  Thanks so much..
0
 
LVL 86

Expert Comment

by:jkr
ID: 9638816
Just one thing to add - don't forget to

CloseHandle ( hStopEvent);

:o)

0
 

Author Comment

by:RowdyOne078
ID: 9638918
Where does that need to be?
0
 

Author Comment

by:RowdyOne078
ID: 9638947
Oh is that to close the

HANDLE  hStopEvent = NULL;

on Exit?

0
 
LVL 86

Expert Comment

by:jkr
ID: 9642427
>>Where does that need to be?

In 'service_main()', right after the call to 'StartService()'
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Suggested Solutions

In days of old, returning something by value from a function in C++ was necessarily avoided because it would, invariably, involve one or even two copies of the object being created and potentially costly calls to a copy-constructor and destructor. A…
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now