hi,
     i write a Win32::Daemon script, and test successfully in my windows
2003 machine,

but when I copy to another windows 2003, it can't be started, and write
below error message in event-viewer:

Timeout (30000 millisecond) waiting for XXXX service to connect.

Please help

below is the code:

use strict;
use warnings;
use Win32;
use Win32::Daemon;

main();

use constant SERVICE_NAME => 'MYSRV';
use constant SERVICE_DESC => 'My service';

sub main
{
   # Get command line argument - if none passed, use empty string
   my $opt = shift (@ARGV) || "";

   # Check command line argument
   if ($opt =~ /^(-i|--install)$/i)
   {
      install_service(SERVICE_NAME, SERVICE_DESC);
   }
   elsif ($opt =~ /^(-r|--remove)$/i)
   {
      remove_service(SERVICE_NAME);
   }
   elsif ($opt =~ /^(--run)$/i)
   {
      # Redirect STDOUT and STDERR to a log file
      # Derive the name of the file from the name of the program
      # The log file will be in the scripts directory, with extension .log
      my ($cwd,$bn,$ext) =
      ( Win32::GetFullPathName($0) =~ /^(.*\\)(.*)\.(.*)$/ ) [0..2] ;
      my $log = $cwd . $bn . ".log";
      # Redirect STDOUT and STDERR to log file
      open(STDOUT, ">> $log") or die "Couldn't open $log for appending:
$!\n";
      open(STDERR, ">&STDOUT");
      # Autoflush, no buffering
      $|=1;

      # Register the events which the service responds to
      Win32::Daemon::RegisterCallbacks( {
            start       =>  \&Callback_Start,
            timer     =>  \&Callback_Running,
            stop        =>  \&Callback_Stop,
            pause       =>  \&Callback_Pause,
            continue    =>  \&Callback_Continue,
         } );
      my %Context = (
         last_state => SERVICE_STOPPED,
         start_time => time(),
      );
      # Start the service passing in a context and indicating to callback
      # using the "Running" event every 2000 milliseconds (2 seconds).
      # NOTE: the StartService method with in 'callback mode' will block, in
other
      # words it won't return until the service has stopped, but the
callbacks below
      # will respond to the various events - START, STOP, PAUSE etc...
      Win32::Daemon::StartService( \%Context, 2000 );

      # Here the service has stopped
      close STDERR; close STDOUT;
   }
   else
   {
      print "No valid options passed - nothing done\n";
   }
}


sub Callback_Running
{
   my( $Event, $Context ) = @_;

   # Note that here you want to check that the state
   # is indeed SERVICE_RUNNING. Even though the Running
   # callback is called it could have done so before
   # calling the "Start" callback.
   if( SERVICE_RUNNING == Win32::Daemon::State() )
   {
      # ... process your main stuff here...
      # ... note that here there is no need to
      #     change the state

      # For now just print hello to the STDOUT, which goes to the log file
      print "Hello!\n";
   }
   $Context->{last_state} = SERVICE_RUNNING;
}

sub Callback_Start
{
   my( $Event, $Context ) = @_;
   # Initialization code
   # ...do whatever you need to do to start...

   print "Starting...\n";

   $Context->{last_state} = SERVICE_RUNNING;
   Win32::Daemon::State( SERVICE_RUNNING );
}

sub Callback_Pause
{
   my( $Event, $Context ) = @_;

   print "Pausing...\n";

   $Context->{last_state} = SERVICE_PAUSED;
   Win32::Daemon::State( SERVICE_PAUSED );
}

sub Callback_Continue
{
   my( $Event, $Context ) = @_;

   print "Continuing...\n";

   $Context->{last_state} = SERVICE_RUNNING;
   Win32::Daemon::State( SERVICE_RUNNING );
}

sub Callback_Stop
{
   my( $Event, $Context ) = @_;

   print "Stopping...\n";

   $Context->{last_state} = SERVICE_STOPPED;
   Win32::Daemon::State( SERVICE_STOPPED );

   # We need to notify the Daemon that we want to stop callbacks and the
service.
   Win32::Daemon::StopService();
}


sub install_service
{
   my ($srv_name, $srv_desc) = @_;
   my ($path, $parameters);

   # Get the program's full filename, break it down into constituent parts
   my $fn = Win32::GetFullPathName($0);
   my ($cwd,$bn,$ext) = ( $fn =~ /^(.*\\)(.*)\.(.*)$/ ) [0..2] ;

   # Determine service's path to executable based on file extension
   if ($ext eq "pl")
   {
      # Source perl script - invoke perl interpreter
      $path = "\"$^X\"";
      # Parameters include extra @INC directories and perl script
      # @INC directories must not end in \ otherwise perl hangs
      my $inc = ($cwd =~ /^(.*?)[\\]?$/) [0];
      # The command includes the --run switch needed in main()
      $parameters = "-I " . "\"$inc\"" . " \"$fn\" --run";
   }
   elsif ($ext eq "exe")
   {
      # Compiled perl script - invoke the compiled script
      $path = "\"$fn\"";
      $parameters = "";
   }
   else
   {
      # Invalid file type?
      die "Can not install service for $fn,
      file extension $ext not supported\n";
   }

   # Populate the service configuration hash
   # The hash is required by Win32::Daemon::CreateService
   my %srv_config = (
      name         => $srv_name,
      display      => $srv_name,
      path         => $path,
      description  => $srv_desc,
      parameters   => $parameters,
      service_type => SERVICE_WIN32_OWN_PROCESS,
      start_type   => SERVICE_AUTO_START,
   );
   # Install the service
   if( Win32::Daemon::CreateService( \%srv_config ) )
   {
      print "Service installed successfully\n";
   }
   else
   {
      print "Failed to install service\n";
   }
}

sub remove_service
{
   my ($srv_name, $hostname) = @_;
   $hostname ||= Win32::NodeName();
   if ( Win32::Daemon::DeleteService ( $srv_name ) )
   {
      print "Service uninstalled successfully\n";
   }
   else
   {
      print "Failed to uninstall service\n";
   }
}
_______________________________________________
Perl-Win32-Users mailing list
Perl-Win32-Users@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs

Reply via email to