Solved

Windows Service Questions

Posted on 2003-10-27
15
6,084 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
ID: 9629103
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
ID: 9629189
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
ID: 9629206
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
PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

 

Author Comment

by:RowdyOne078
ID: 9629264
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
ID: 9629290
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
ID: 9629335
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
ID: 9629859
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
 
LVL 86

Expert Comment

by:jkr
ID: 9629914
>>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
ID: 9630056
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
ID: 9630114
>>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
ID: 9630214
That caused all kinds of problems... Why didnt they have a cpp example!!

Thanks
0
 

Author Comment

by:RowdyOne078
ID: 9630274
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
ID: 9631039
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
ID: 9634234
BTW, do you have _any_ files left in this project that have a .c extension?
0
 

Author Comment

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

Featured Post

NAS Cloud Backup Strategies

This article explains backup scenarios when using network storage. We review the so-called “3-2-1 strategy” and summarize the methods you can use to send NAS data to the cloud

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
IntroductionThis article is the second in a three part article series on the Visual Studio 2008 Debugger.  It provides tips in setting and using breakpoints. If not familiar with this debugger, you can find a basic introduction in the EE article loc…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
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.

825 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