hi:
I try to rewrite the code with old style without callback. according to the win32::daemon document, this kind of style is obsolete and we should use callback.
but the old style won't leak memory. code below. I named the service "memory-noleak".
#!/usr/bin/perl
use strict;
use warnings;
use Win32::Daemon;
use Getopt::Long;
my @cmd = @ARGV;
my ($opt_g,$opt_h,$opt_i,$opt_r);
if (! GetOptions('g=s' =>\$opt_g, 'h' => \$opt_h, 'i' => \$opt_i, 'r'
+=>\$opt_r)){
print "command line wrong !!!\n";
exit(1);
}
if ($opt_h or ! @cmd){
print <<EOF;
Usage: memory-noleak [options]
test perl service memory-noleak
-i install memory-noleak Service
-r remove memory-noleak Service
-h help message
-g (internal use only)
EOF
exit(0);
}
# get program name
our $fn = Win32::GetFullPathName($0);
our ($cwd,$bn,$ext) = ($fn =~ /^(.*\\)(.*)\.(.*)$/ )[0..2];
if ($opt_i){
# install service
# Determine service's path to executable based on file extension
my ($path,$parameters);
if ($ext eq "pl"){
# Source perl script - invoke perl interpreter
$path = "\"$^X\"";
# The command includes the -g go switch needed to enter servic
+e mode
$parameters = "\"$fn\" -g go";
}elsif ($ext eq "exe"){
# Compiled perl script - invoke the compiled script
$path = "\"$fn\"";
$parameters = "-g go";
}else{
# Invalid file type?
print "Can not install service for $fn,file extension $ext not
+ supported\n";
exit(1);
}
# Populate the service configuration hash
my %srv_config = (
name => "memory-noleak",
display => "memory-noleak",
path => $path,
description => "memory-noleak",
parameters => $parameters,
service_type => SERVICE_WIN32_OWN_PROCESS,
start_type => SERVICE_AUTO_START
);
# Install the service
if (Win32::Daemon::CreateService(\%srv_config)){
print "memory-noleak Service installed successfully\n";
}else{
print "Failed to install service: $!\n";
exit(1);
}
}elsif ($opt_r){
# remove service
if (Win32::Daemon::DeleteService("memory-noleak")){
print "memory-noleak Service uninstalled successfully\n";
}else{
print "Failed to uninstall service: $!\n";
exit(1);
}
}elsif ($opt_g eq "go"){
my $SERVICE_SLEEP_TIME = 30;
my $PrevState = SERVICE_START_PENDING;
Win32::Daemon::StartService();
while( SERVICE_STOPPED != ( my $State = Win32::Daemon::State())){
if( SERVICE_START_PENDING == $State ){
# Initialization code
Win32::Daemon::State( SERVICE_RUNNING );
$PrevState = SERVICE_RUNNING;
}elsif( SERVICE_STOP_PENDING == $State ){
# "Stopping...";
Win32::Daemon::State( SERVICE_STOPPED );
$PrevState = SERVICE_STOPPED;
next;
}elsif( SERVICE_RUNNING == $State ){
}else{
Win32::Daemon::State( $PrevState );
}
Win32::Sleep( $SERVICE_SLEEP_TIME );
}
Win32::Daemon::StopService();
exit(0);
}