Link to home
Start Free TrialLog in
Avatar of rian
rian

asked on

Set Time Notification

I am writing a VC++ program for NT 4.0+. I am trying to have my program run all the time. However, it needs to be signalled at a certain time based on the INI entry. Say 18:00 in the evening on certain days. I would like my program to Wait for the time to pass by before it starts any processing or consume CPU time. I have used WaitforSingleObject before but I am not sure if I can signal this API at a certain time.
Is there an Function which allows me to do that. SOme code will be appreciated too.
ASKER CERTIFIED SOLUTION
Avatar of jkr
jkr
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of nietod
nietod

Or if the application has a user intereface, create a timer with SetTimer() and you will receive WM_TIMER messages periodically.  Check the time when you get the message to see if it is time to perform your processing.
The only difficulty is to compute the amount of milliseconds as the argument for sleep, you could use something like that:

#include <windows.h>
#include <time.h>
#include <stdio.h>

void main( void )
{
   struct tm when;
   time_t now, result;
   int    hour;
   DWORD  dwSleepTime;

   time( &now );
   when = *localtime( &now );
   printf( "Current time is %s\n", asctime( &when ) );
   printf( "Which hour to execute: " );
   scanf( "%d", &hour );

   when.tm_hour +=  hour;

   printf( "Will execute at %s\n", asctime( &when ) );

   if( (result = mktime( &when )) != (time_t)-1 )
   {
     // 'result' holds the time to execute in seconds since Jan 1st 1970
     // 'now' holds the actual time in seconds since Jan 1st 1970

     dwSleepTime = ( DWORD) ( result - now) * 1000;

     Sleep ( dwSleepTime);

     printf ( "\nWAKING UP!!\n");

   }
   else
      perror( "mktime failed" );

}

nietod is right - but the method to compute the timer 'interval' is the same as shown above ;-)

It'd be quite similar (just forget about 'printf()' and friends):


   if( (result = mktime( &when )) != (time_t)-1 )
   {
     // 'result' holds the time to execute in seconds since Jan 1st 1970
     // 'now' holds the actual time in seconds since Jan 1st 1970

     dwSleepTime = ( DWORD) ( result - now) * 1000;

     SetTimer ( hMyWnd, 0, dwSleepTime, NULL);
   }

Or, alternatively

     SetTimer ( NULL, unMyID, dwSleepTime, MyTimerProc);
One thing I forgot to mention - 'Sleep()' only works < 49 days (DWORD overflow <-> milliseconds ;-)
Alternatively you can use NetScheduleJobAdd function(). The NetScheduleJobAdd function submits a program to run at a specified future time and date. You can also use this run a program at a remote system.

You can pass the program name as a comand in AT_INFO structure.which is a paparameter to NetScheduleJobAdd() function.

Additionally you will have control if you want your program to run on a periodic basic also.


NET_API_STATUS NetScheduleJobAdd(
LPWSTR Servername,       
LPBYTE Buffer,       
LPDWORD JobId       
);       


Buffer is pointer to strcuture of type
typedef struct _AT_INFO {
    DWORD   JobTime;
    DWORD   DaysOfMonth;
    UCHAR   DaysOfWeek;
    UCHAR   Flags;
    LPWSTR  Command;
} AT_INFO, *PAT_INFO, *LPAT_INFO;
 
This way you may not be bound with functionality problems of Sleep() etc (49.7 days limit).
Please see MSDN help for more details.


Hope this helps to acheive your goal.
Ufolk123
Avatar of rian

ASKER

I appreciate all the help. However, I was trying to find a way where I could use a function similar to WaitforSingleObject or MultipleObject.

Thanks a lot..