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

Hello Monks

EDIT: Ok so I may have been misleading everyone. I have been able to install the script as a service but for some reason I get an error when running it as a service. What runs perfectly from a command line fails as a service with the below error:

Error 1053: The service did not respond to the start or control request in a timely fashion

I have been trying to wrap my head around using Win32::Daemon to have a perl script and/or pp converted executable of the same script run as a service and I can't seem to figure out how this is done. I have tried using the Windows "sc create..." command with the .exe file but that does not work so I am obviously missing the Win32::Daemon portion in the script

The script simply monitors a network stream and based on the output it will write to a file, see below

#!/usr/bin/perl use strict; use IO::Socket; use POSIX; use warnings; use Config::Simple; use Win32::Daemon; sub logMonitor{ #subrouting to connect to the PBX log and monitor for +the Emergency calls my ($HOST, $PORT)= @_; OUTER: if (my $sock = new IO::Socket::INET(PeerAddr => $HOST, Peer +Port => $PORT,Proto => "tcp",)) { while (<$sock>) { s/^\0+//; # Remove leading null characters chomp ($_); my $data = substr($_, 1,17); my $event = substr ($data, 2,1); my $hr = substr ($data, 3,2); my $min = substr ($data,5,2); my $year = substr($data, 9,4); my $mon = substr($data, 13,2); my $day = substr ($data,15,2); #print "$hr:$min on $year-$mon-$day \n"; if ($event eq "A") { my $agent = substr($_, 17,4); # print "\n Agent $agent logged in \n" ; my $output = "Agent $agent logged in at $hr:$min on ex +t $year"; filePrint($output); } } else { print "Failed to connect to $HOST on $PORT. Will retry in a mi +nute.\n"; sleep 60; goto OUTER; } } #End of monitor subroutine sub filePrint{ #write data to file with date and time stamp my ($DATA)= @_; print "$DATA\n"; my $dateStamp = strftime '%Y-%m-%d', localtime; my $file = "$dateStamp.log"; my $timeStamp = strftime '%H:%M:%S', localtime; if (-f $file){ open (my $fh,'>>', $file); print $fh "$timeStamp | $DATA\n"; close $file; } else { open (my $fh,'>', $file); print $fh "$timeStamp | $DATA\n"; close $file; } }# End of filePrint routine my $cfg = new Config::Simple(); $cfg->read('config.ini'); my $HOST = $cfg->param("pbx"); my $PORT = $cfg->param("port"); logMonitor($HOST, $PORT); #Open the log monitoring subroutine

Can anyone explain to me how to use Win32::Daemon with this script to create a service from it? Right now it will run as a command line tool

many thanks!

Replies are listed 'Best First'.
Re: Help converting to a Windows service
by beech (Parson) on Mar 23, 2017 at 21:39 UTC

    Can anyone explain to me how to use Win32::Daemon with this script to create a service from it? Right now it will run as a command line tool

    Hi,

    Follow the examples from the documentation?

    Maybe Win32::Daemon::Simple is easier?

      Ok, maybe I didn't explain myself correctly, I have been able to use the Win32::Daemon to create the service and it appears in the Services list as I would expect but it fails to run. I get an

      Error 1053: The service did not respond to the start or control request in a timely fashion

      I am not sure if this is due to the script I am using or if the actual Win::Daemon process is responsible.

      I did a test with a very simple script below and get the same error. I am not sure what I am doing wrong

      #! perl -slw use strict; use Win32; open LOG, '>', 'c:\Mitel\ACD\service.log' or die; select LOG; $|++; Win32::MsgBox( 'From test.pl at ' . localtime, 0, "test.pl" ); while( sleep 5 ) { Win32::MsgBox( 'From test.pl at ' . localtime, 0, "test.pl" ); print scalar localtime; } close LOG;

        Hi,

        What example are you following?

        Have you seen https://metacpan.org/pod/Win32%3A%3ADaemon#Example-1:-Simple-Service?

        It says

        This example service will delete all .tmp files from the c:\temp directory every time it starts. It will immediately terminate.
        use Win32::Daemon; # Tell the OS to start processing the service... Win32::Daemon::StartService(); # Wait until the service manager is ready for us to continue... while( SERVICE_START_PENDING != Win32::Daemon::State() ) { sleep( 1 ); } # Now let the service manager know that we are running... Win32::Daemon::State( SERVICE_RUNNING ); # Okay, go ahead and process stuff... unlink( glob( "c:\\temp\\*.tmp" ) ); # Tell the OS that the service is terminating... Win32::Daemon::StopService();

        Does that make sense ?