Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

Perl won't run as NT service

by Anonymous Monk
on Feb 01, 2002 at 03:38 UTC ( [id://142583]=perlquestion: print w/replies, xml ) Need Help??

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi all ActivePerl vers 5.6.1 Script run fine from command promp, But not when called by an NT service. This is not a script problem, perl itself is not running. Tried to change account used by the service, tried system, administrator, ... nothing helped Would appreciate any hints / solutions TIA

Replies are listed 'Best First'.
Re: Perl won't run as NT service
by impossiblerobot (Deacon) on Feb 01, 2002 at 05:17 UTC
    I don't know if you've tried this, but:
    From the ActiveState Documentation:
    You can run your Perl scripts as Windows NT Services via a program called srvany.exe, which comes with the Windows NT Resource Kit. Once srvany.exe is installed, read the srvany.wri file which should be with it. This document will explain how to set up registry entries for your new service.
    After you are set up, to run your script as a service do:
    x:>srvany perl script.pl
    It's in the 'Windows Specifics' section.

    Impossible Robot
Re: Perl won't run as NT service
by cmilfo (Hermit) on Feb 01, 2002 at 05:32 UTC
    I've used Perl in a service and called from services quite a bit now (mostly using the Perl Dev Kit from ActiveState). So here are some questions that might help me/us help you!

    Are you receiving any errors?
    Is anything being written to the Event Log?
    Are you using the Perl Dev Kit -- PerlSvc (I have a whole other list of questions, if so)?
    As mentioned in an above post, are you giving full path to modules (Windows paths are notorious for not working)?
    Are the modules using other modules that may not be in your path?
    Is Perl associated with .pl files? If not, are you calling the script with perl <full_path>\<script_name>?

    If I think of any more, I will post here again. Good luck!

Re: Perl won't run as NT service
by Sniper (Scribe) on Feb 01, 2002 at 15:27 UTC
    Hi

    how do you run your script as service ?
    are you using PerlSvc, SrvAny (from NT Resources Kit), Win32::Daemon ?
    Win32::Daemon is good and free and the script using it is a TRUE native NT Service


    David "Sniper" Rigaudiere

      "Win32::Daemon is good and free and the script using it is a TRUE native NT Service"

      I downloaded and installed Win32::Daemon for Perl 5.6. I then started a simpe evaluation for a potential use in our shop.

      My major problem is that the documentation leaves a lot to whish. Some methods are mentioned while their parameter lists are completely absent from the documentation. I even tried to re-generate the doc using pod2html, but the new doc wasn't better than the on-line version.

      For instance, I'm able to find the parameters for installing a service, but only in the example given. Not in the docs. The example invites the less carefull developer to install the test service. (I assume it will work, but I still haven't run it.)
      At the same time, I am still unable to find the parameters for un-installing the same service. (Which is why I didn't install the "test service" in the first place.) And of course there is no example code to un-install the installed test-service either. I guess this is covered in the commercial book.

      Of course, I could send for the authors book at amazon.com, but it doesn't really feel right as long as we're talking "free". Agreed, noone said the book would be free, but providing free software (as stated on the site) with commercial documentation is not really what I had expected.

      And please bare in mind that I was not hoping to get the complete book for free. I just wanted to have a simple POD for all methods in the module.

      You know, like the CGI.pm module. It's documented with POD. The documentation is complete if you know what you want to do and why. (This is what I'd expect from "free" software.) If, OTOH, you need to learn the concepts of GCI programming with Perl, you may need to buy the commercial book. A much more appealing concept IMHO.

      "Livet är hårt" sa bonden.
      "Grymt" sa grisen...

        I agree with you,
        I will write and publish here even a tutorial for Win32::Daemon,
        but time is not my friend :- (

        David "Sniper" Rigaudiere

Re: Perl won't run as NT service
by trs80 (Priest) on Feb 01, 2002 at 04:45 UTC
    It could be that the script is relying on files that are in the @INC path when run from the command line and not when it is run by a service. In other words are there module or configuration files that the scripts need to run that aren't in the path for the service.
    If this is the case there are at least two options.
    1) add a use lib "/path/to/modules" in the script
    2) move the script and dependent files into a path in the @INC for the service.
Re: Perl won't run as NT service
by johannz (Hermit) on Feb 02, 2002 at 01:15 UTC

    I've had a lot of luck using Win32::Daemon from Roth Consulting. You can get a ppm for it, and it plays well with ActivePerl 5.6.1.

    Here are some convienence modules and sample code I wrote to make working with it easier

    This service watches a file, and when it changes, reads it, and re-writes a batch file. This allows me to have an alias like feature in Win2K.

    go2.pl

    An example service

    #!perl # Go2.pl - a service to create a shortcut batch file # Includes service installer and remover BEGIN { use Win32::EventLog::Carp; # open(STDERR, '>E:\Commands\Daemons\stderr.log'); } use lib qw(e:\commands\daemons); use lib qw(e:\lib\perl); use Getopt::Long; use Data::Dumper; use Win32::Daemon::Simple; use Win32::Daemon::Go2; use Win32::EventLog::Carp; use strict; use warnings; my ($install, $remove, $manual); GetOptions('install' => \$install, 'remove' => \$remove, 'manual' => \ +$manual); my $daemon = new Win32::Daemon::Go2( name => 'go2_installer', display => 'Go2 installer', description => 'This will create the go2 batch file', ); if ($install) { $daemon->install() } elsif ($remove) { $daemon->remove() } elsif ($manual) { print "Running body\n"; $daemon->body() } else { $daemon->run() }; exit;

    Win32::Daemon::Simple

    A utility class I wrote that encapsulates the examples provided by Roth Consulting

    package Win32::Daemon::Simple; use Data::Dumper; use Win32; use Win32::Daemon; use Win32::EventLog::Carp; use Module::Reload; use strict; use warnings; sub new { my $type = shift; my $self = bless {}, ref($type) || $type; $self->_init(@_); $self; } sub _init { my $self = shift; my %params = @_; $self->getServiceInfo(%params); # Stuff the user can override $self->{sleepTime} = $params{sleepTime} || 50; # 50 Milliseconds; # Stuff that we use internally $self->{prevState} = undef; } sub run { my $self = shift; my ($state, $message); #Win32::Daemon::AcceptedControls(SERVICE_ACCEPT_STOP | SERVICE_ACC +EPT_PAUSE_CONTINUE | SERVICE_ACCEPT_SHUTDOWN); $self->{prevState} = SERVICE_START_PENDING; Win32::Daemon::StartService(); while( SERVICE_STOPPED != ( $state = Win32::Daemon::State() ) ) { croak "Forced Stop" if (-e 'E:\commands\Daemons\stop.dat'); Module::Reload->check(); if ($state == SERVICE_START_PENDING) { $self->_startPending() + } elsif ($state == SERVICE_STOP_PENDING) { $self->_stopPending() + } elsif ($state == SERVICE_PAUSE_PENDING) { $self->_pausePending +(); next } elsif ($state == SERVICE_CONTINUE_PENDING) { $self->_continueP +ending(); next } elsif ($state == SERVICE_RUNNING) { $self->body } else {$self->_unhandledMessage()}; if (SERVICE_CONTROL_NONE != ($message = Win32::Daemon::QueryLa +stMessage( 1 )) ) { $self->_controlInterrogate() if ($message == SERVICE_CONTR +OL_INTERROGATE); $self->_controlShutdown() if ($message == SERVICE_CONTROL_ +SHUTDOWN); } Win32::Sleep( $self->{sleepTime} ); } Win32::Daemon::StopService(); } sub body { Win32::EventLog::Carp::click('Abstract Base Class body called'); } sub _startPending { # Initialization code Win32::Daemon::State( SERVICE_RUNNING ); $_[0]->{prevState} = SERVICE_RUNNING; } sub _stopPending { # "Stopping..."; Win32::Daemon::State( SERVICE_STOPPED ); $_[0]->{prevState} = SERVICE_STOPPED; } sub _pausePending { # "Pausing..."; Win32::Daemon::State( SERVICE_PAUSED ); $_[0]->{prevState} = SERVICE_PAUSED; } sub _continuePending { # "Resuming..."; Win32::Daemon::State( SERVICE_RUNNING ); $_[0]->{prevState} = SERVICE_RUNNING; } sub _controlInterrogate { # Got here if the Service Control Manager is requesting # the current state of the service. This can happen for # a variety of reasons. Report the last state we set. my $self = shift; Win32::Daemon::State( $self->{prevState} ); } sub _controlShutdown { # Yikes! The system is shutting down. We had better clean up # and stop. # Tell the SCM that we are preparing to shutdown and that we expec +t # it to take 25 seconds (so don't terminate us for at least 25 sec +onds)... Win32::Daemon::State( SERVICE_STOP_PENDING, 25000 ); } sub _unhandledMessage { Win32::Daemon::State( $_[0]->{prevState} ); } sub getServiceInfo { my $self = shift; my %params = @_; my $this = ($self->{serviceInfo} ||= {}); return %$this if (keys(%$this)); for (qw[machine name display path user pwd description parameters] +) { $this->{$_} = $params{$_}; } croak "Service Name required" unless $this->{name}; $this->{machine} ||= ''; $this->{display} ||= $self->{name}; $this->{path} ||= $^X; $this->{user} ||= ''; $this->{pwd} ||= ''; $this->{description} ||= $0; $this->{parameters} ||= $0; %$this; } sub install { my $self = shift; print Dumper($self->{serviceInfo}); if( Win32::Daemon::CreateService( $self->{serviceInfo} ) ) { print "Successfully added.\n"; } else { print "Failed to add service: " . Win32::FormatMessage( Win32: +:Daemon::GetLastError() ) . "\n"; } } sub remove { my $self = shift; my $serviceName = $self->{serviceInfo}{name}; if ( Win32::Daemon::DeleteService($serviceName)) { print "Successfully removed '$serviceName'.\n"; } else { print "Error: "; print Win32::Daemon::GetLastError(); } } 1;

    Win32::Daemon::Go2

    The actual body of the service. This is called by Win32::Daemon::Simple each time through the loop.

    package Win32::Daemon::Go2; use Win32::Daemon::Simple; @ISA = qw(Win32::Daemon::Simple); use strict; use warnings; use File::stat; my $datafile = 'e:\\Commands\\go2.dat'; my $outfile = 'e:\\Commands\\go2.bat'; sub body { my $self = shift; return unless (-e $datafile); $self->{last_mod} ||= 0; my $sb = stat($datafile); if ($self->{last_mod} != $sb->mtime) { $self->{last_mod} = $sb->mtime; my %batch; open(INPUT, $datafile); while (my $target = <INPUT>) { chomp($target); my ($label, $dest) = split('~', $target, 2); $label =~ s/\s/_/g; $dest =~ s{/}{\\}g; my ($drive, @path) = split(/\\/, $dest); $batch{$label} = { drive => lc $drive, path => \@path, } }; open(OUTPUT, ">$outfile") or croak $@; local $\ = "\n"; print OUTPUT '@echo off'; print OUTPUT 'if "" == "%1" ('; print OUTPUT "\techo \t$_" for sort(grep !/^!/, keys(%batch)); print OUTPUT "\tgoto EOF"; print OUTPUT ')'; for my $label (reverse sort keys(%batch)) { if ($label =~ /^!/) { print OUTPUT join('', 'if "', $label, '" == "%1" ('); print OUTPUT "\tpushd ", join('\\', $batch{$label}{dri +ve}, @{$batch{$label}{path}}, '%2'); print OUTPUT "\tcmd /k"; print OUTPUT "\tpopd"; print OUTPUT "\tcls"; print OUTPUT "\tgoto EOF"; print OUTPUT ')'; } else { print OUTPUT join('', 'if "', $label, '" == "%1" ('); print OUTPUT "\t", $batch{$label}{drive}; print OUTPUT "\tcd \\", join('\\', @{$batch{$label}{pa +th}}, '%2'); print OUTPUT "\tgoto EOF"; print OUTPUT ')'; }; }; print OUTPUT 'echo Destination not found: %*'; print OUTPUT 'echo Try editing E:\command\go2.dat'; print OUTPUT ':EOF'; close(OUTPUT); } } 1;
Re: Perl won't run as NT service
by belg4mit (Prior) on Feb 01, 2002 at 03:44 UTC
    There are a couple ways of doing this, the easiest is to get an application to wrap the script in that handles the service<=>windows interface. I have gone this route before, colleagues also used it for java stuff.

    --
    perl -pe "s/\b;([st])/'\1/mg"

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://142583]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others cooling their heels in the Monastery: (5)
As of 2025-03-26 07:55 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    When you first encountered Perl, which feature amazed you the most?










    Results (67 votes). Check out past polls.

    Notices?
    erzuuliAnonymous Monks are no longer allowed to use Super Search, due to an excessive use of this resource by robots.