#////////////////////////////////////////////////////////////////////////////// #// #// Callback.pl #// Win32::Daemon Perl extension test script employing Callbacks #// #// Copyright (c) 1998-2008 Dave Roth #// Courtesy of Roth Consulting #// http://www.roth.net/ #// #// This file may be copied or modified only under the terms of either #// the Artistic License or the GNU General Public License, which may #// be found in the Perl 5.0 source kit. #// #// 2008.03.24 :Date #// 20080324 :Version #////////////////////////////////////////////////////////////////////////////// # Demonstration of an AutoStart Service using the Win32::Daemon # Perl extension. This service will auto launch applications # when it starts. Effectively enabling Windows to auto start # applications at boot time, before a user ever logs on. use Win32::Daemon; my %List; my $START_TIME = time(); my $DEFAULT_CALLBACK_TIMER = 2000; # For DEBUG version ONLY!! if( Win32::Daemon::IsDebugBuild() ) { # Win32::Daemon::DebugOutputPath( "\\\\.\\pipe\\syslog" ); } my ( $SCRIPT_DIR, $SCRIPT_FILE_NAME ) = ( Win32::GetFullPathName( $0 ) =~ /^(.*)\\([^\\]*)$/ ); $| = 1; #my $LOG_FILE = shift @ARGV || "$SCRIPT_DIR\\$SCRIPT_FILE_NAME.log"; my $LOG_FILE = "\\\\.\\pipe\\syslog"; if( open( LOG, ">$LOG_FILE" ) ) { my $StartTime = localtime( $START_TIME ); my $BackupHandle = select( LOG ); $| = 1; select( $BackupHandle ); print LOG << "EOT" # Service Starting # Script: $0 # Perl: $X # PID: $$ # Date: $StartTime EOT } Win32::Daemon::RegisterCallbacks( \&CallbackRoutine ); Log( "Starting service" ); %Context = ( last_state => SERVICE_STOPPED, count => 0, start_time => time(), ); Win32::Daemon::StartService( \%Context, $DEFAULT_CALLBACK_TIMER ); Log( "Shutting down the service." ); Log( "Start time: " . localtime( $Context{start_time} ) ); Log( "End time: " . localtime() ); Log( "Total running callback count: $Context{count}" ); # # Define the callback routine # sub CallbackRoutine { my( $State, $Context ) = @_; if( SERVICE_RUNNING == $State ) { $Context->{count}++; Log( "Running!!! Count=$Context->{count}\n" ); Log( "Callback timer: " . Win32::Daemon::CallbackTimer() ); } elsif( SERVICE_START_PENDING == $State ) { # Initialization code $Context->{last_state} = SERVICE_RUNNING; Win32::Daemon::State( SERVICE_RUNNING ); Log( "Service initialized. Setting state to Running." ); } elsif( SERVICE_PAUSE_PENDING == $State ) { $Context->{last_state} = SERVICE_PAUSED; Win32::Daemon::State( SERVICE_PAUSED ); Win32::Daemon::CallbackTimer( 0 ); Log( "Pausing." ); } elsif( SERVICE_CONTINUE_PENDING == $State ) { $Context->{last_state} = SERVICE_RUNNING; Win32::Daemon::State( SERVICE_RUNNING ); Win32::Daemon::CallbackTimer( $DEFAULT_CALLBACK_TIMER ); Log( "Resuming from paused state." ); } elsif( SERVICE_STOP_PENDING == $State ) { $Context->{last_state} = SERVICE_STOPPED; Win32::Daemon::State( [ state => SERVICE_STOPPED, error => 1234 ] ); Log( "Stopping service." ); # We need to notify the Daemon that we want to stop callbacks and the service. Win32::Daemon::StopService(); } elsif( SERVICE_EVENT_SHUTDOWN == $State ) { Log( "Event: SHUTTING DOWN! *** Stopping this service ***" ); # We need to notify the Daemon that we want to stop callbacks and the service. Win32::Daemon::StopService(); } elsif( SERVICE_EVENT_PRESHUTDOWN == $State ) { Log( "Event: Preshutdown!" ); } elsif( SERVICE_EVENT_INTERROGATE == $State ) { Log( "Event: Interrogation!" ); } elsif( SERVICE_EVENT_NETBINDADD == $State ) { Log( "Event: Adding a network binding!" ); } elsif( SERVICE_EVENT_NETBINDREMOVE == $State ) { Log( "Event: Removing a network binding!" ); } elsif( SERVICE_EVENT_NETBINDENABLE == $State ) { Log( "Event: Network binding has been enabled!" ); } elsif( SERVICE_EVENT_NETBINDDISABLE == $State ) { Log( "Event: Network binding has been disabled!" ); } elsif( SERVICE_EVENT_DEVICEEVENT == $State ) { Log( "Event: A device has issued some event of some sort!" ); } elsif( SERVICE_EVENT_HARDWAREPROFILECHANGE == $State ) { Log( "Event: Hardware profile has changed!" ); } elsif( SERVICE_EVENT_POWEREVENT == $State ) { Log( "Event: Some power event has occured!" ); } elsif( SERVICE_EVENT_SESSIONCHANGE == $State ) { Log( "Event: User session has changed!" ); } else { # Take care of unhandled states by setting the State() # to whatever the last state was we set... Win32::Daemon::State( $Context->{last_state} ); Log( "Got an unknown state: $State" ); } return(); } sub Log { my( $Message ) = @_; if( fileno( LOG ) ) { print LOG "[" . localtime() . "] $Message\n"; } }