Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Win32::Daemon

by Macphisto (Hermit)
on Jun 18, 2001 at 18:30 UTC ( [id://89302]=perlquestion: print w/replies, xml ) Need Help??

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

I'm poking around the bits and pieces of David Roths Win32::Daemon and attempting to learn how to use it to create and install services on Win32 machines. So, using some code from Tim Roth's Win32 Perl Scripting book, I've created the two small scripts below which I am attempting to get working correctly so I can modify it a piece at a time, and learn what all I can do with Win32::Daemon. The code is as follows:
use Win32::Daemon; open ( OUT, "C:\\Out.txt" ) || die ( "Unable to open file: $!" ); Win32::Daemon::StartService(); while ( SERVICE_STOPPED != ( $State = Win32::Daemon::State() ) ) { if ( SERVICE_START_PENDING == $State ) { print OUT "Starting Service\n"; Win32::Daemon::State( SERVICE_RUNNING ); } elsif ( SERVICE_PAUSE_PENDING == $State ) { print OUT "Pausing Service\n"; Win32::Daemon::State( SERVICE_PAUSED ); } elsif ( SERVICE_CONTINUE_PENDING == $State ) { print OUT "Resuming Service\n"; Win32::Daemon::State( SERVICE_RUNNING ); } elsif ( SERVICE_STOP_PENDING == $State ) { print OUT "Service Stopping"; Win32::Daemon::State( SERVICE_STOPPED ); } elsif ( SERVICE_RUNNING == $State ) { print OUT "Service Running"; } sleep(5); } Win32::Daemon::StopService();
I install the daemon with this:
#!/usr/bin/perl -w use Win32::Daemon; my %ServiceConfig = ( name => "TestService", display => "Testing a Perl Created Service", path => $^X, user => '', passwd => '', parameters => 'c:\Perl\scripts\TestService.pl', ); if ( Win32::Daemon::CreateService ( \%ServiceConfig ) ) { print "The '$ServiceConfig{display}' service"; print "was successfully installed.\n"; } else { print "Failed to add '$ServiceConfig{dislay}' service\n"; print "Error:"; print Win32::FormatMessage( Win32::Daemon::GetLastError() ), "\n"; }
And it installs happily. But when I open up Services, and choose "Start" I get: The service did not respond to the start or control request in a timely fashion

Any ideas?
Macphisto the I.T. Ninja

Everyone has their demons....

Replies are listed 'Best First'.
(tye)Re: Win32::Daemon
by tye (Sage) on Jun 18, 2001 at 18:38 UTC

    First, you are opening OUT for input.

    Second, if you don't know why it is failing, then get more information:

    BEGIN { open( STDERR, ">>c:/daemon.err" ) or die "invisible error"; warn "$0 started ".localtime().$/; }
    Now you can see if it is dying and why and you can add more warn statements with timestamps so you can see where it is hanging and for how long.

            - tye (but my friends call me "Tye")

      I recently used Win32::Daemon to create a connection between a Linux client and an NT database. It might have been quicker to use DBI::Proxy, but I learned more this way. I had some problems with my script, which might have been detected had I used something like this BEGIN block.

      I deliberately added a line 'use Blarfle;' to my working script. Blarfle.pm does not exist (well, maybe it does on CPAN... I haven't looked). When I start my service from the control panel (NT 4.0), I get to watch an hour glass until it displays "Error 2186: The service is not responding to the control function."

      I added this BEGIN block after the 'use Blarfle;' statement:

      # *SNIP*
      use Blarfle;
      
      BEGIN {
          open(STDERR, ">>d:/daemon.err") or die "invisible error";
          warn "$0 started" . localtime() . "\n";
      }
      
      # *SNIP*
      
      I didn't get any output in my d:\daemon.err file.

      Next, I moved the 'use Blarfle;' so it was after the BEGIN block:

      # *SNIP*
      BEGIN {
          open(STDERR, ">>d:/daemon.err") or die "invisible error";
          warn "$0 started" . localtime() . "\n";
      }
      
      use Blarfle;
      
      # *SNIP*
      
      Again, I received Error 2186. However, I still didn't see any output in d:\daemon.err.

      What did I miss?

        Well, there are obvious things like not having a D: drive... But anything that would cause that open to fail would give that symptom, for example, perhaps the credentials of the service don't have access to append to that file (for example, if D: is a remote file system, then the service probably won't have any access to it no matter what permissions you set on the file).

        Or perhaps you were looking at the file using a tool that opened the file w/o specifying shared access so that the daemon couldn't open it.

        I'd first check that the script manages to write to the daemon.err file when run not as a service as well as when run as a service with the "user Blarfle;" line commented out. That should narrow things down quite a bit.

        You could also use try other methods for getting the "invisible error" to not be invisible such as:

        open(...) or system( "net send %computername% " . qq("Can't open d:/daemon.err: $!; $^E") );
        (though I don't think that will work from a service either) or using something to pop up a message box (this should work if you configure the service to have access to the interactive desktop).

        It is sad that the WinNT Service Manager is so stupid when it comes to noticing and reporting that the service that it started has died. But then, if you look very far into the design of the service manager (called "the SCuM"), you quickly realize that it isn't a very good design in a lot of ways (just ask the guys who had to hack it to pieces to make it even usable for "clustering" -- "dogfood" indeed). /:

                - tye (but my friends call me "Tye")
      tye,
      Keen eye you got there, buddy. Thanks. Its too early for me and I've had too few cups of coffee...it seems to be working now.

      Thanks.

      Macphisto the I.T. Ninja

      Everyone has their demons....
Re: Win32::Daemon
by donaldm314 (Pilgrim) on Jun 19, 2001 at 01:25 UTC

    We have a defect tracking database which runs on NT. We needed to be able to connect to this database from our Linux CVS server.

    Just last week, I created an NT Service with Win32::Daemon. Using DBI and DBD::ODBC, I connect to the defect database. Using RPC.pm (from Sririam's Advanced Perl Programming), I listen on a port for clients. Whenever developers commit files to the repository, perl scripts update the defect database, via RPC.pm. Works like a charm!


    I had never created an NT service before, and found the process a little bit un-forgiving. If there was an error in my script, and the Service Control Manager (SCM) could not start the service, it would respond with things like Error 2816. Not very helpful.

    It turned out my problem was related to one of my own modules, installed in d:/code/perl/. I traditionally use PERL5LIB (as a user env. variable) to let Perl know where this module resides. Hence, when I tested my perl service from a command prompt (while logged in as myself) it worked like a charm.

    However, I was installing my perl service with no user specified, as you were in your tests. My PERL5LIB was not being set, so Perl didn't know where to find my module. The script died, and after the SCM timed out, it said 'Error 2186.' I wasted hours trying to diagnose this.

    Once I finally figured out my bone-headed mistake, I moved my module to a directory in the default @INC.

    On a related note, my ODBC Data Source was originally configured as a User DSN. Because my service was installed without a user specified... Error 2140. Once I changed my data source to a System DSN, my perl daemon was able to connect to the database.

    Now that I've got my NT Service running, I plan to use Win32::Daemon for absolutely everything. ;-)

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others browsing the Monastery: (3)
As of 2024-04-19 21:25 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found