use strict; use warnings; use Win32::Daemon; use constant SERVICE_POLL_RATE => 1E3; if (my $opt = shift @ARGV){ my %serviceSettings = ( name => 'MyExampleService', #name => 'MyExampleService2', display => 'My Example Service', #display => 'My Example Service 2', path => $^X, parameters => $0, ); if ($opt eq '-i') { installService(%serviceSettings); } elsif ($opt eq '-r'){ deleteService(%serviceSettings); } exit; } my %Context = ( last_state => SERVICE_STOPPED, start_time => time, ); my $logFile = $0; $logFile =~ s/\w+$/log/; open STDOUT, ">", $logFile; $|=1; print "Register callbacks\n"; Win32::Daemon::RegisterCallbacks( { start => \&callbackStart, stop => \&callbackStop, running => \&callbackRunning, pause => \&callbackPause, continue => \&callbackContinue, } ); print "Start service\n"; Win32::Daemon::StartService( \%Context, SERVICE_POLL_RATE ); print "Service finished, cleaning up\n"; close STDOUT; ################################################################## sub deleteService { my (%serviceSettings) = @_; Win32::Daemon::DeleteService('', $serviceSettings{name}) or die "Delete service failed, error:\n\t".Win32::Daemon::GetLastError().": ".Win32::FormatMessage(Win32::Daemon::GetLastError()); print "Service deleted\n"; } sub installService { my (%serviceSettings) = @_; Win32::Daemon::CreateService(\%serviceSettings) or die "Install service failed, error:\n\t".Win32::Daemon::GetLastError().": ".Win32::FormatMessage(Win32::Daemon::GetLastError()); print "Service created\n"; } sub callbackContinue { my ($event, $Context) = @_; print "Event $event: Continue ...\n"; $Context->{last_state} = SERVICE_RUNNING; Win32::Daemon::State( SERVICE_RUNNING ); } sub callbackPause { my ($event, $Context) = @_; print "Event $event: Pause ...\n"; $Context->{last_state} = SERVICE_PAUSED; Win32::Daemon::State( SERVICE_PAUSED ); } sub callbackRunning { my ($event, $Context) = @_; return Win32::Daemon::State() if SERVICE_PAUSED eq Win32::Daemon::State(); if (SERVICE_RUNNING eq Win32::Daemon::State()) { my ($ss, $mm, $hh, $dd, $nn, $yy) = gmtime; my $timestamp = sprintf("%04d%02d%02d %02d:%02d:%02d", $yy + 1900, $nn + 1, $dd, $hh, $mm, $ss); print "$timestamp: Running ...\n" if (time % 60); } Win32::Daemon::State(); } sub callbackStart { my ($event, $Context) = @_; print "Event $event: Start ...\n"; $Context->{last_state} = SERVICE_RUNNING; Win32::Daemon::State( SERVICE_RUNNING ); } sub callbackStop { my ($event, $Context) = @_; print "Event $event: Stopped ...\n"; $Context->{last_state} = SERVICE_STOPPED; Win32::Daemon::State( SERVICE_STOPPED ); Win32::Daemon::StopService(); }