Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Getting SERVICE_STOPPED immediately when running test\daemon.pl #15

Open
hakonhagland opened this issue Jun 30, 2020 · 3 comments
Open

Comments

@hakonhagland
Copy link
Contributor

hakonhagland commented Jun 30, 2020

On Windows 10 using Strawberry Perl version 5.30.1, Win32-Daemon version 20190315. When I try to run the program daemon.pl supplied in the test folder of the distribution:

use strict;
use warnings;
use Data::Dumper qw(Dumper);
use Win32::Daemon;

Win32::Daemon::StartService();
my %List;
my $SLEEP_TIMEOUT = 100; # This value is in milliseconds
my $START_TIME = time();
my ( $DB_DIR, $DB_FILE_NAME ) = ( Win32::GetFullPathName( $0 ) =~ /^(.*)\\([^\\]*)$/ );
$DB_FILE_NAME =~ s/\..*?$/.log/;
print "DB_DIR: $DB_DIR\n";
print "DB_FILE_NAME : $DB_FILE_NAME\n";
if( open( LOG, ">$DB_DIR\\$DB_FILE_NAME" ) )
{
    my $StartTime = localtime( $START_TIME );
    $| = 1;
    print LOG << "EOT"
# Service Starting
# Script: $0
# PID: $$
# Date: $StartTime
EOT
}

Log( "Starting service" );
Win32::Daemon::StartService();
Log( "Entering service loop" );
our $LastState = SERVICE_STOPPED;
our $State;
while( SERVICE_STOPPED != ( $State = Win32::Daemon::State() ) )
{
  if( SERVICE_START_PENDING == $State )
  {
    # Initialization code
    $LastState = SERVICE_RUNNING;
#    Win32::Daemon::State( [ state => SERVICE_RUNNING, error => NO_ERROR ] );
    Win32::Daemon::State( SERVICE_RUNNING );
    Log( "Service initialized. Setting state to Running." );
  }
  elsif( SERVICE_PAUSE_PENDING == $State )
  {
    $LastState = SERVICE_PAUSED;
    Win32::Daemon::State( SERVICE_PAUSED );
    Log( "Pausing." );
    next;
  }
  elsif( SERVICE_CONTINUE_PENDING == $State )
  {
    $LastState = SERVICE_RUNNING;
    Win32::Daemon::State( SERVICE_RUNNING );
    Log( "Resuming from paused state." );
    next;
  }
  elsif( SERVICE_STOP_PENDING == $State )
  {
    $LastState = SERVICE_STOPPED;
    Win32::Daemon::State( [ state => SERVICE_STOPPED, error => 1234 ] );
    Log( "Stopping service." );
    next;
  }
  else
  {
    # Take care of unhandled states by setting the State()
    # to whatever the last state was we set...
    Win32::Daemon::State( $LastState );
  }
  Log("Sleeping...");
  Win32::Sleep( $SLEEP_TIMEOUT );
}
Log( "Done");
print "StopService() return value: ", Win32::Daemon::StopService(), "\n";


sub Log
{
    my( $Message ) = @_;
    if( fileno( LOG ) )
    {
        print LOG "[" . localtime() . "] $Message\n";
    }
}

When I run this program it exits immediately with output:

> C:\Users\hakon\perl\service\deamon>perl p.pl
DB_DIR: C:\Users\hakon\perl\service\deamon
DB_FILE_NAME : p.log
StopService() return value: 1

The output of the log file p.log is:

> C:\Users\hakon\perl\service\deamon>type p.log
# Service Starting
# Script: p.pl
# PID: 8900
# Date: Tue Jun 30 20:01:46 2020
[Tue Jun 30 20:01:46 2020] Starting service
[Tue Jun 30 20:01:46 2020] Entering service loop
[Tue Jun 30 20:01:46 2020] Done

What am I missing here? Why am I getting SERVICE_STOPPED immediately before entering the while loop?

See also this question on stackoverflow.com

@ikegami
Copy link

ikegami commented Jun 30, 2020

The scripts expects to be run as a service, but you run it from the console. See "Example 3" in the docs for how to set it up as a service.

@hakonhagland
Copy link
Contributor Author

@ikegami I tried to start it first as you suggested using this script create.pl :

use strict;
use warnings;
use Win32::Daemon;
my $ServicePath = $^X;  #'C:\Strawberry\perl\bin\perl.exe';
my $ServiceParams = 'C:\Users\hakon\perl\service\daemon\p.pl';

my %service_info = (
    name    => 'my test service',
    display => 'my service',
    path    => $ServicePath,
    description => 'simple service test',
    parameters => $ServiceParams,
    service_type => SERVICE_WIN32_OWN_PROCESS,
    start_type => SERVICE_AUTO_START);

if(Win32::Daemon::CreateService( \%service_info))
{
    print "successfully added \n";
}
else
{
    print "failed to add service: " . Win32::FormatMessage( Win32::Daemon::GetLastError());
}

Running the script seems to work fine:

C:\Users\hakon\perl\service\deamon>perl create.pl
successfully added

But the service daemon.pl did not start. I think the service was simply added to the system (not started). How can I start it immediately? I opened the Services app as administrator and found the service in the list of services known to the app. I then right-clicked on it and chose Start from the popup menu. This gave me the following error message:

service

@hakonhagland
Copy link
Contributor Author

I think I found the error, I had misspelled the directory path to the service:

my $ServiceParams = 'C:\Users\hakon\perl\service\daemon\p.pl';

so now I can start it successfully from the Services app. But I cannot stop it from the app. I also wonder how I can start the service automatically (not using the Services app)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants