From OrganicDesign Wiki
#
use Win32::Daemon; # David Roth's module for NT-services, see http://www.roth.net/
sub serviceError {
my $lastError = Win32::FormatMessage( Win32::Daemon::GetLastError() );
logAdd "$_[0]: $lastError";
}
# Need list of running peers into @peers
# Install the service
if ( exists $config{ install } ) {
# check if peer of this name/port not already running
if ( Win32::Daemon::CreateService( {
machine => '',
name => $peer,
display => "$daemon: $peer/$port",
path => $cwd,
user => '',
pwd => '',
description => "$title ($daemon) is running as \"$peer\" on port $port",
parameters => $cmd
} ) ) { logAdd "Peer service installed successfully." }
else { serviceError "Peer service failed to install"; exit; }
}
# Remove the named service and exit
if ( exists $config{ remove } ) {
serviceError "Couldn't remove \"$peer\" service" unless Win32::Daemon::DeleteService( '', $peer );
}
# Start the service
if ( exists $config{ install } or exists $config{ start } ) {
# check if peer of this name/port not already running
# this should be one of the callbacks
if ( Win32::Daemon::StartService() ) { logAdd "\"$peer\" service started successfully." }
else { serviceError "Couldn't start \"$peer\" service"; exit; }
# Get rid of cmd console
use Win32::Console;
my $CONSOLE = new Win32::Console();
$CONSOLE->Free();
}
# Main service loop
logAdd "Entering service loop";
my $lastState = SERVICE_STOPPED;
while ( ( my $state = Win32::Daemon::State() ) != SERVICE_STOPPED ) {
logAdd "State: $state";
$SERVICE_RUNNING = 0;
if ( $state == SERVICE_START_PENDING ) {
Win32::Daemon::State( $lastState = SERVICE_RUNNING );
logAdd "$daemon service initialized. Setting state to Running.";
}
elsif ( $state == SERVICE_PAUSE_PENDING ) {
Win32::Daemon::State( $lastState = SERVICE_PAUSED );
logAdd "Pausing $daemon service...";
next;
}
elsif ( $state == SERVICE_CONTINUE_PENDING ) {
Win32::Daemon::State( $lastState = SERVICE_RUNNING );
logAdd "Resuming $daemon service...";
next;
}
elsif ( $state == SERVICE_STOP_PENDING ) {
Win32::Daemon::State( $lastState = SERVICE_STOPPED );
logAdd "Stopping $daemon service...";
next;
}
elsif ( $state == SERVICE_RUNNING ) {
$SERVICE_RUNNING = 1;
# Main reduction loop needs to go in here?
# - no we should use callbacks for start/stop etc
# - this "main-loop" doesn't need to be here
}
else { Win32::Daemon::State( $lastState ) }
Win32::Sleep( 500 );
}
# Stop the service
logAdd Win32::Daemon::StopService();
logAdd "$daemon service stopped.";