Solved

Windows Service Questions

Posted on 2003-10-27
15
6,063 Views
Last Modified: 2013-12-14
I have a few quick questions about windows services.

1)  What function from the ATL COM created functions do I add the fuction calls for my code I want to run?
2) Does my code need to loop, or does the service repeat?
3) once I finish the implementation how do you install the service on a different computer?

Thanks
Greg R
0
Comment
Question by:RowdyOne078
  • 8
  • 7
15 Comments
 
LVL 86

Expert Comment

by:jkr
Comment Utility
Are you sure you want an ATL COM service or is that an requirement? I'd suggest going this way: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndllpro/html/msdn_ntservic.asp ("Creating a Simple Win32 Service in C++")
0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
BTW, if you have/want to stick with ATL, I'd suggest reading http://www.codeguru.com/atl/MailslotRepositrySrv.html ("Creating a Windows NT Service by Using ATL ")
0
 

Author Comment

by:RowdyOne078
Comment Utility
i dont need ATL. Im looking into the first post.  Is NTService.h something I need to write or where can I find it?

Greg
0
 

Author Comment

by:RowdyOne078
Comment Utility
Is there anywhere I can see a full example of code using the Simple Win32 Service in C++?

Greg
0
 
LVL 86

Accepted Solution

by:
jkr earned 500 total points
Comment Utility
There used to be a download link on that page - anyway, a pretty good service sample comes with the VS6 samples that are available from http://www.microsoft.com/downloads/details.aspx?FamilyId=AF0A6060-6566-408F-9F11-EA2C80B8CAA0&displaylang=en
0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
Hum, there's more:

http://www.naughter.com/serv.html ("CNTService v1.34 A class framework for developing NT services in MFC")

and see also the 'NT Service' section on http://www.codeguru.com/system/index.shtml
0
 

Author Comment

by:RowdyOne078
Comment Utility
ok I got the sample and I am playing with it.  My only question is in the following code, where do I put the call to my code that performs the tasks?
-----------------------------------------------------
Thanks


// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (C) 1993-1997  Microsoft Corporation.  All Rights Reserved.
//
//  MODULE:   service.c
//
//  PURPOSE:  Implements functions required by all services
//            windows.
//
//  FUNCTIONS:
//    main(int argc, char **argv);
//    service_ctrl(DWORD dwCtrlCode);
//    service_main(DWORD dwArgc, LPTSTR *lpszArgv);
//    CmdInstallService();
//    CmdRemoveService();
//    CmdDebugService(int argc, char **argv);
//    ControlHandler ( DWORD dwCtrlType );
//    GetLastErrorText( LPTSTR lpszBuf, DWORD dwSize );
//
//  COMMENTS:
//
//  AUTHOR: Craig Link - Microsoft Developer Support
//


#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;
}
0
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!

 
LVL 86

Expert Comment

by:jkr
Comment Utility
>>where do I put the call to my code that performs the tasks?

Exactly here:

   // 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 ); // <--- Here !!!

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


'ServiceStart()' is - technically speaking - 'your' part in the above skeleton service to be 'filled with the meat', the functionality of the service. Replace that function with the code that you want the service to perform.
0
 

Author Comment

by:RowdyOne078
Comment Utility
OK Im having one last problem...

When I try to build I get the crazy error

C:\Program Files\Microsoft Visual Studio\VC98\INCLUDE\eh.h(32) : fatal error C1189: #error :  "eh.h is only for C++!"

I have never seen this, how can I get rid of it?  Thanks for all the help.


Here is my code

// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (C) 1993-1997  Microsoft Corporation.  All Rights Reserved.
//
//  MODULE:   simple.c
//
//  PURPOSE:  Implements the body of the service.
//            The default behavior is to open a
//            named pipe, \\.\pipe\simple, and read
//            from it.  It the modifies the data and
//            writes it back to the pipe.
//
//  FUNCTIONS:
//            ServiceStart(DWORD dwArgc, LPTSTR *lpszArgv);
//            ServiceStop( );
//
//  COMMENTS: The functions implemented in simple.c are
//            prototyped in service.h
//              
//
//  AUTHOR: Craig Link - Microsoft Developer Support
//


#include <stdio.h>
#include <stdlib.h>
#include <fstream>
#include <string>
#include <time.h>
#include <direct.h>
#include <io.h>

using namespace std;

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

#include "service.h"





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

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


// this event is signalled when the
// service should end
//
HANDLE  hServerStopEvent = NULL;


//
//  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 default behavior is to open a
//    named pipe, \\.\pipe\simple, and read
//    from it.  It the modifies the data and
//    writes it back to the pipe.  The service
//    stops when hServerStopEvent is signalled
//
VOID ServiceStart (DWORD dwArgc, LPTSTR *lpszArgv)
{
    char optionFilePath[200];
      char djEnginePath[200];
      int pollingInterval=0;
      char errorLog[30];
      char fThread[10];
      char archivedPath[200];

    // report the status to the service control manager.
    //
    if (!ReportStatusToSCMgr(
        SERVICE_START_PENDING, // service state
        NO_ERROR,              // exit code
        3000))                 // wait hint
   
    //
    // Service is now running, perform work until shutdown
    //
      
    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);
    }



}


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


//---------------------------------------------------------------------------------
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();
}
//----------------------------------------------------------------------
0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
>>C:\Program Files\Microsoft Visual Studio\VC98\INCLUDE\eh.h(32) : fatal error C1189: #error :  "eh.h is only for C++!"

Hm, the file is named 'service.c', so the compiler assumes that it is plain C code - and you are clearly using C++ statemants - rename the file to 'service.cpp' and re-add it to your project (better do so for all files that have a .c extension)
0
 

Author Comment

by:RowdyOne078
Comment Utility
That caused all kinds of problems... Why didnt they have a cpp example!!

Thanks
0
 

Author Comment

by:RowdyOne078
Comment Utility
Now that Im using CPP and a make file I get all kinds of Errors.  

How can I fix these?
Thanks

main.obj : error LNK2001: unresolved external symbol "public: virtual __thiscall std::ios_base::~ios_base(void)" (??1ios_base@std@@UAE@XZ)
main.obj : error LNK2001: unresolved external symbol "void __cdecl std::_Xlen(void)" (?_Xlen@std@@YAXXZ)
main.obj : error LNK2001: unresolved external symbol "void __cdecl std::_Xran(void)" (?_Xran@std@@YAXXZ)
main.obj : error LNK2001: unresolved external symbol "public: void __thiscall std::ios_base::clear(int,bool)" (?clear@ios_base@std@@QAEXH_N@Z)
main.obj : error LNK2001: unresolved external symbol "bool __cdecl std::uncaught_exception(void)" (?uncaught_exception@std@@YA_NXZ)
main.obj : error LNK2001: unresolved external symbol "__int64 const std::_Fpz" (?_Fpz@std@@3_JB)
main.obj : error LNK2001: unresolved external symbol "private: static class std::locale::_Locimp * std::locale::_Locimp::_Global" (?_Global@_Locimp@locale@std@@0PAV123@A)
main.obj : error LNK2001: unresolved external symbol "private: static class std::locale::_Locimp * __cdecl std::locale::_Init(void)" (?_Init@locale@std@@CAPAV_Locimp@12@XZ)
main.obj : error LNK2001: unresolved external symbol "struct _iobuf * __cdecl std::__Fiopen(char const *,int)" (?__Fiopen@std@@YAPAU_iobuf@@PBDH@Z)
main.obj : error LNK2001: unresolved external symbol "protected: void __thiscall std::ios_base::_Addstd(void)" (?_Addstd@ios_base@std@@IAEXXZ)
main.obj : error LNK2001: unresolved external symbol "protected: void __thiscall std::ios_base::_Init(void)" (?_Init@ios_base@std@@IAEXXZ)
main.obj : error LNK2001: unresolved external symbol "public: bool __thiscall std::locale::_Iscloc(void)const " (?_Iscloc@locale@std@@QBE_NXZ)
main.obj : error LNK2001: unresolved external symbol "public: class std::locale::facet const * __thiscall std::locale::_Getfacet(unsigned int,bool)const " (?_Getfacet@locale@std@@QBEPBVfacet@12@I_N@Z)
main.obj : error LNK2001: unresolved external symbol "public: static class std::locale::id std::ctype<char>::id" (?id@?$ctype@D@std@@2V0locale@2@A)
main.obj : error LNK2001: unresolved external symbol "private: static int std::locale::id::_Id_cnt" (?_Id_cnt@id@locale@std@@0HA)
main.obj : error LNK2001: unresolved external symbol "private: static short const * const std::ctype<char>::_Cltab" (?_Cltab@?$ctype@D@std@@0PBFB)
main.obj : error LNK2001: unresolved external symbol "public: __thiscall std::_Locinfo::~_Locinfo(void)" (??1_Locinfo@std@@QAE@XZ)
main.obj : error LNK2001: unresolved external symbol "public: __thiscall std::_Locinfo::_Locinfo(char const *)" (??0_Locinfo@std@@QAE@PBD@Z)
main.obj : error LNK2001: unresolved external symbol __Getctype
main.obj : error LNK2001: unresolved external symbol __Tolower
main.obj : error LNK2001: unresolved external symbol __Toupper
main.obj : error LNK2001: unresolved external symbol "public: class std::locale & __thiscall std::locale::_Addfac(class std::locale::facet *,unsigned int,unsigned int)" (?_Addfac@locale@std@@QAEAAV12@PAVfacet@12@II@Z)
main.obj : error LNK2001: unresolved external symbol __Getcvt
simple.obj : error LNK2001: unresolved external symbol _GrabVariables
simple.exe : fatal error LNK1120: 24 unresolved externals
NMAKE : fatal error U1077: 'link' : return code '0x460'
Stop.
Error executing NMAKE.
0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
There seems to be a problem with the project settings. Bring up that dialog, go to the C++  settings select "Code Generation" and change "Use Runtime Library" to "Multithreaded DLL" (I am hoping that this will load reasonable defaults for your project)
0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
BTW, do you have _any_ files left in this project that have a .c extension?
0
 

Author Comment

by:RowdyOne078
Comment Utility
Ive got it compiling now, but still have problems, im going to open a new question... Thanks for you constant help.
0

Featured Post

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

Join & Write a Comment

Suggested Solutions

  Included as part of the C++ Standard Template Library (STL) is a collection of generic containers. Each of these containers serves a different purpose and has different pros and cons. It is often difficult to decide which container to use and …
Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.
The viewer will learn how to synchronize PHP projects with a remote server in NetBeans IDE 8.0 for Windows.

744 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

16 Experts available now in Live!

Get 1:1 Help Now