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

G'day,

I'm trying to set up a service on Windows NT using Dave Roths Win32::Daemon module. When I try to start it, after waiting for about 3 minutes, I'm getting the following message : "Service is not responding to the control function".

This seems to be caused by using self written modules. If I remove 'use testPackage', everything seems to run normal and the service gets started.

Did anyone already strugle with this problem before ?

Many thanks in advance,
Cruelty.

------------

package testPackage; sub new { my $that = shift; my $class = ref($that) || $that; my $self; $self->{DEBUG} = shift; bless $self, $class; return $self; } 1; ----------- use Win32::Daemon; use strict; use testPackage; my $LOGFILE = "test.log"; sub verbose { warn "TRACE ($$) : $_[0]"; } open (STDERR, ">$LOGFILE") || die "cannot open log file $LOGFILE\n"; Win32::Daemon::StartService(); my $prevState = SERVICE_STOPPED; while (SERVICE_STOPPED != ( my $State = Win32::Daemon::State() ) ) { if ( SERVICE_START_PENDING == $State ) { Win32::Daemon::State( SERVICE_RUNNING ); $prevState = SERVICE_RUNNING; verbose("$0 started at " . localtime().$/); } elsif ( SERVICE_PAUSE_PENDING == $State ) { verbose("Pausing Service\n"); Win32::Daemon::State( SERVICE_PAUSED ); $prevState = SERVICE_PAUSED; next; } elsif ( SERVICE_CONTINUE_PENDING == $State ) { verbose("Resuming Service\n"); Win32::Daemon::State( SERVICE_RUNNING ); $prevState = SERVICE_RUNNING; next; } elsif ( SERVICE_STOP_PENDING == $State ) { verbose("Service Stopping"); Win32::Daemon::State( SERVICE_STOPPED ); $prevState = SERVICE_STOPPED; next; } elsif ( SERVICE_RUNNING == $State ) { if ($DEBUG) { verbose("Service Running"); } if ( $DEBUG ) { verbose ("Waiting 100 seconds to continue\n"); } sleep(100); } else { # unknown state : reset to previous state Win32::Daemon::State( $prevState ); } sleep(1); } Win32::Daemon::StopService();

Edit kudra, 2001-09-17 Added code tags

Replies are listed 'Best First'.
Re: Win32::Daemon problem
by $code or die (Deacon) on Sep 17, 2001 at 22:44 UTC
    #...snip elsif ( SERVICE_RUNNING == $State ) { if ($DEBUG) { verbose("Service Running"); } if ( $DEBUG ) { verbose ("Waiting 100 seconds to continue\n"); } sleep(100); } #...snip
    I think you want to reduce that sleep 100 to something smaller, like sleep 2. If you need a longer sleep, then split it up and do a Win32::Daemon::State() call between each one. The Win32 service control manager polls all active services every now and then and it needs to receive a response within 15 seconds or so, otherwise it says that the service isn't responding. IIRC, Dave mentions this in the docs.

    As for whether this fixes your problem, I can't say at the moment - I don't have a Win32 machine to test it on right now.

    Hope this helps.

    __________________________________________________________
    Simon Flack ($code or die)
    $,=reverse'"ro_';s,$,\$,;s,$,lc ref sub{},e;$,
    =~y'_"' ';eval"die";print $_,lc substr$@,0,3;

      You're right, thanks for the spot but that's not what was causing the problem.

      After some research, I found that the real problem was that the perl interpreter wasn't able to find the package I was trying to include because the service gets started from a different directory than the one where I placed my script and module.

      This problem is now solved by adding the directory to the @INC list :

      use lib "c:/mypath";

      Regards,

      <ruelty

        Ahh. I've run into similar problems before. Win32 services are more difficult to debug because you can't see what's going on. What I've done in the past is log errors to a text file. This is fine for development, but in production you probably want to use the Event Log, with Win32::EventLog or Win32::EventLog::Message - I don't have a link, but I think it's another one of Dave Roth's.

        I find something along these lines useful:
        BEGIN { $SIG{__WARN__} = $SIG{__DIE__} = sub { open ERRORLOG, ">>/myerror.log" or die "error opening logfile"; print ERRORLOG, scalar localtime, " - $0\n", @_, "\n\n"; close ERRORLOG; } }
        I think this would have caught your problem and written it to a log file.

        John M. Dlugosz pointed out recently that you can also use Win32::MessageBox from within a Service. So you could replace that logfile with a more immediate and visual prompt.

        Simon Flack ($code or die)
        $,=reverse'"ro_';s,$,\$,;s,$,lc ref sub{},e;$,
        =~y'_"' ';eval"die";print $_,lc substr$@,0,3;