Click here to get back home

Windows services in PERL

 HomeNewsGroups | Search | About
 comp.lang.perl.modules    Post an article   get this group's latest topics as an RSS feed add this group's latest topics to your My MSN content add this group's latest topics to your My Yahoo content
Subject Author Date
Windows services in PERL harvar007 07-13-2006
Posted by harvar007 on July 13, 2006, 3:01 pm
Please log in for more thread options


Hi

I am trying to create a win32 service using the module win32:deamon. I
wrote a simple code and tried to get that running before I went to the
actual one. I am actually able to successfully create the service and
see the same in the Management Console, but when I try to right click
and say Start I get "error :1053 the service did not respond or start
to the control request in a timely fashion"

Can any one please, let me know what might be wrong in this scenario?

Here is my sample code which I was trying to get installed!

use Win32::Daemon;
Win32::Daemon::StartService();
while( SERVICE_START_PENDING != Win32::Daemon::State() )
{
sleep( 1 );
}
Win32::Daemon::State( SERVICE_RUNNING );
unlink( glob( "c:\temp\*.tmp" ) );
Win32::Daemon::StopService();

Thanks
Harini


Posted by harryfmudd [AT] comcast [DOT] on July 14, 2006, 11:48 am
Please log in for more thread options


harvar007@yahoo.com wrote:
> Hi
>
> I am trying to create a win32 service using the module win32:deamon. I
> wrote a simple code and tried to get that running before I went to the
> actual one. I am actually able to successfully create the service and
> see the same in the Management Console, but when I try to right click
> and say Start I get "error :1053 the service did not respond or start
> to the control request in a timely fashion"
>
> Can any one please, let me know what might be wrong in this scenario?
>
> Here is my sample code which I was trying to get installed!
>
> use Win32::Daemon;
> Win32::Daemon::StartService();
> while( SERVICE_START_PENDING != Win32::Daemon::State() )
> {
> sleep( 1 );
> }
> Win32::Daemon::State( SERVICE_RUNNING );
> unlink( glob( "c:\temp\*.tmp" ) );
> Win32::Daemon::StopService();
>
> Thanks
> Harini
>

It has been a while, but ...

The first suggestion I have is to check the success of
Win32::Daemon::StartService (), with something like

Win32::Daemon::StartService () or do {
my $err = "Failed to start service\n" .
        Win32::FormatMessage (
         Win32::Daemon::GetLastError ());
# Log the error somewhere, then
die $err;
};

The second is that you probably want to handle the SERVICE_NOT_READY
state by going to state SERVICE_START_PENDING. In fact, the more I think
about it, the more I think this may be your problem. Maybe your event
loop should be something like

while (1)
{
my $state = Win32::Daemon::State ();
if ($state == SERVICE_NOT_READY)
{
        Win32::Daemon::State (SERVICE_START_PENDING);
} elsif ($state == SERVICE_START_PENDING)
{
        last;
}
sleep (1);        # or Win32::Sleep (1000);
}

Less likely, but possible:

* You might need to set the state to SERVICE_RUNNING in response to the
SERVICE_CONTINUE_PENDING state, in addition to the SERVICE_START_PENDING
state.

* Jenda's code (see below) sets the state to SERVICE_RUNNING in response
to state 0x0080. You might want to try the same, in addition to the others.

* You _might_ also need to respond to the OS messages you get from
calling Win32::Daemon::QueryLastMessage -- at least to
SERVICE_CONTROL_INTERROGATE (respond with the state you believe the
service to be in) in your event loop. If your event loop ran
indefinitely you might want to respond to SERVICE_CONTROL_SHUTDOWN
(system shutdown) by setting your service to SERVICE_STOP_PENDING and
cleaning up.

Better than all this, though, is a trick I picked up from Jenda
Krynicky's Win32::Daemon::Simple (see http://jenda.krynicky.cz/). I did
not use this module itself because it required replacing ActiveState's
Win32::Registry with an incompatible version from Jenda, and I didn't
want to do that because it made an otherwise-straightforward maintenance
situation complicated. Of course, the trade-off was that an otherwise
simple daemon became complicated.

The trick allows you to run your service interactively (i.e. not as a
service, but so that you actually see the output), and the essence of
the trick is the following:


# After you have successfully called Win32::Daemon::StartService:

my $save_state = SERVICE_NOT_READY;        # in case interactive.


# Wherever you query the service state, code

service_state ();

# Wherever you set the service state, code

service_state ($whatever_the_new_state_is);

# As a special case of the above, if you are responding to
# SERVICE_CONTROL_INTERROGATE (see above), code

service_state ($save_state);


###############################
#
# With your other internal subroutines:


# Return true if running from the command line, false otherwise.

BEGIN {
my $cmdlin = Win32::Console::_GetConsoleTitle () ? 1 : 0;
sub CMDLINE
}

# Wrap Win32::Daemon::State so we can run interactively.

sub service_state {
return CMDLINE () ? $save_state : Win32::Daemon::State ()
unless @_;
push @_, 25000        # Milliseconds
if $_[0] == SERVICE_STOP_PENDING && @_ == 1;
Win32::Daemon::State (@_) unless CMDLINE ();
$save_state = shift;
return $save_state;
}

One last thought: You might think about logging to a file, so you can
tell what your service is doing.

Tom Wyant

Posted by harvar007 on July 14, 2006, 12:15 pm
Please log in for more thread options


Hi Tom,

Thanks a ton for the eloborate suggestions! Will try them and let you
know my outcome...

Harini

harryfmudd [AT] comcast [DOT] net wrote:
> harvar007@yahoo.com wrote:
> > Hi
> >
> > I am trying to create a win32 service using the module win32:deamon. I
> > wrote a simple code and tried to get that running before I went to the
> > actual one. I am actually able to successfully create the service and
> > see the same in the Management Console, but when I try to right click
> > and say Start I get "error :1053 the service did not respond or start
> > to the control request in a timely fashion"
> >
> > Can any one please, let me know what might be wrong in this scenario?
> >
> > Here is my sample code which I was trying to get installed!
> >
> > use Win32::Daemon;
> > Win32::Daemon::StartService();
> > while( SERVICE_START_PENDING != Win32::Daemon::State() )
> > {
> > sleep( 1 );
> > }
> > Win32::Daemon::State( SERVICE_RUNNING );
> > unlink( glob( "c:\temp\*.tmp" ) );
> > Win32::Daemon::StopService();
> >
> > Thanks
> > Harini
> >
>
> It has been a while, but ...
>
> The first suggestion I have is to check the success of
> Win32::Daemon::StartService (), with something like
>
> Win32::Daemon::StartService () or do {
> my $err = "Failed to start service\n" .
>         Win32::FormatMessage (
>          Win32::Daemon::GetLastError ());
> # Log the error somewhere, then
> die $err;
> };
>
> The second is that you probably want to handle the SERVICE_NOT_READY
> state by going to state SERVICE_START_PENDING. In fact, the more I think
> about it, the more I think this may be your problem. Maybe your event
> loop should be something like
>
> while (1)
> {
> my $state = Win32::Daemon::State ();
> if ($state == SERVICE_NOT_READY)
> {
>         Win32::Daemon::State (SERVICE_START_PENDING);
> } elsif ($state == SERVICE_START_PENDING)
> {
>         last;
> }
> sleep (1);        # or Win32::Sleep (1000);
> }
>
> Less likely, but possible:
>
> * You might need to set the state to SERVICE_RUNNING in response to the
> SERVICE_CONTINUE_PENDING state, in addition to the SERVICE_START_PENDING
> state.
>
> * Jenda's code (see below) sets the state to SERVICE_RUNNING in response
> to state 0x0080. You might want to try the same, in addition to the others.
>
> * You _might_ also need to respond to the OS messages you get from
> calling Win32::Daemon::QueryLastMessage -- at least to
> SERVICE_CONTROL_INTERROGATE (respond with the state you believe the
> service to be in) in your event loop. If your event loop ran
> indefinitely you might want to respond to SERVICE_CONTROL_SHUTDOWN
> (system shutdown) by setting your service to SERVICE_STOP_PENDING and
> cleaning up.
>
> Better than all this, though, is a trick I picked up from Jenda
> Krynicky's Win32::Daemon::Simple (see http://jenda.krynicky.cz/). I did
> not use this module itself because it required replacing ActiveState's
> Win32::Registry with an incompatible version from Jenda, and I didn't
> want to do that because it made an otherwise-straightforward maintenance
> situation complicated. Of course, the trade-off was that an otherwise
> simple daemon became complicated.
>
> The trick allows you to run your service interactively (i.e. not as a
> service, but so that you actually see the output), and the essence of
> the trick is the following:
>
>
> # After you have successfully called Win32::Daemon::StartService:
>
> my $save_state = SERVICE_NOT_READY;        # in case interactive.
>
>
> # Wherever you query the service state, code
>
> service_state ();
>
> # Wherever you set the service state, code
>
> service_state ($whatever_the_new_state_is);
>
> # As a special case of the above, if you are responding to
> # SERVICE_CONTROL_INTERROGATE (see above), code
>
> service_state ($save_state);
>
>
> ###############################
> #
> # With your other internal subroutines:
>
>
> # Return true if running from the command line, false otherwise.
>
> BEGIN {
> my $cmdlin = Win32::Console::_GetConsoleTitle () ? 1 : 0;
> sub CMDLINE
> }
>
> # Wrap Win32::Daemon::State so we can run interactively.
>
> sub service_state {
> return CMDLINE () ? $save_state : Win32::Daemon::State ()
> unless @_;
> push @_, 25000        # Milliseconds
> if $_[0] == SERVICE_STOP_PENDING && @_ == 1;
> Win32::Daemon::State (@_) unless CMDLINE ();
> $save_state = shift;
> return $save_state;
> }
>
> One last thought: You might think about logging to a file, so you can
> tell what your service is doing.
>
> Tom Wyant


Posted by harini.gopi on July 14, 2006, 3:30 pm
Please log in for more thread options


that didnt work either!
so i downloaded an utility called "srvany.exe" which apparently seems
to have fixed the problem! am not sure though why it couldnt start in
the normal manner...

Harini

harryfmudd [AT] comcast [DOT] net wrote:
> harvar007@yahoo.com wrote:
> > Hi
> >
> > I am trying to create a win32 service using the module win32:deamon. I
> > wrote a simple code and tried to get that running before I went to the
> > actual one. I am actually able to successfully create the service and
> > see the same in the Management Console, but when I try to right click
> > and say Start I get "error :1053 the service did not respond or start
> > to the control request in a timely fashion"
> >
> > Can any one please, let me know what might be wrong in this scenario?
> >
> > Here is my sample code which I was trying to get installed!
> >
> > use Win32::Daemon;
> > Win32::Daemon::StartService();
> > while( SERVICE_START_PENDING != Win32::Daemon::State() )
> > {
> > sleep( 1 );
> > }
> > Win32::Daemon::State( SERVICE_RUNNING );
> > unlink( glob( "c:\temp\*.tmp" ) );
> > Win32::Daemon::StopService();
> >
> > Thanks
> > Harini
> >
>
> It has been a while, but ...
>
> The first suggestion I have is to check the success of
> Win32::Daemon::StartService (), with something like
>
> Win32::Daemon::StartService () or do {
> my $err = "Failed to start service\n" .
>         Win32::FormatMessage (
>          Win32::Daemon::GetLastError ());
> # Log the error somewhere, then
> die $err;
> };
>
> The second is that you probably want to handle the SERVICE_NOT_READY
> state by going to state SERVICE_START_PENDING. In fact, the more I think
> about it, the more I think this may be your problem. Maybe your event
> loop should be something like
>
> while (1)
> {
> my $state = Win32::Daemon::State ();
> if ($state == SERVICE_NOT_READY)
> {
>         Win32::Daemon::State (SERVICE_START_PENDING);
> } elsif ($state == SERVICE_START_PENDING)
> {
>         last;
> }
> sleep (1);        # or Win32::Sleep (1000);
> }
>
> Less likely, but possible:
>
> * You might need to set the state to SERVICE_RUNNING in response to the
> SERVICE_CONTINUE_PENDING state, in addition to the SERVICE_START_PENDING
> state.
>
> * Jenda's code (see below) sets the state to SERVICE_RUNNING in response
> to state 0x0080. You might want to try the same, in addition to the others.
>
> * You _might_ also need to respond to the OS messages you get from
> calling Win32::Daemon::QueryLastMessage -- at least to
> SERVICE_CONTROL_INTERROGATE (respond with the state you believe the
> service to be in) in your event loop. If your event loop ran
> indefinitely you might want to respond to SERVICE_CONTROL_SHUTDOWN
> (system shutdown) by setting your service to SERVICE_STOP_PENDING and
> cleaning up.
>
> Better than all this, though, is a trick I picked up from Jenda
> Krynicky's Win32::Daemon::Simple (see http://jenda.krynicky.cz/). I did
> not use this module itself because it required replacing ActiveState's
> Win32::Registry with an incompatible version from Jenda, and I didn't
> want to do that because it made an otherwise-straightforward maintenance
> situation complicated. Of course, the trade-off was that an otherwise
> simple daemon became complicated.
>
> The trick allows you to run your service interactively (i.e. not as a
> service, but so that you actually see the output), and the essence of
> the trick is the following:
>
>
> # After you have successfully called Win32::Daemon::StartService:
>
> my $save_state = SERVICE_NOT_READY;        # in case interactive.
>
>
> # Wherever you query the service state, code
>
> service_state ();
>
> # Wherever you set the service state, code
>
> service_state ($whatever_the_new_state_is);
>
> # As a special case of the above, if you are responding to
> # SERVICE_CONTROL_INTERROGATE (see above), code
>
> service_state ($save_state);
>
>
> ###############################
> #
> # With your other internal subroutines:
>
>
> # Return true if running from the command line, false otherwise.
>
> BEGIN {
> my $cmdlin = Win32::Console::_GetConsoleTitle () ? 1 : 0;
> sub CMDLINE
> }
>
> # Wrap Win32::Daemon::State so we can run interactively.
>
> sub service_state {
> return CMDLINE () ? $save_state : Win32::Daemon::State ()
> unless @_;
> push @_, 25000        # Milliseconds
> if $_[0] == SERVICE_STOP_PENDING && @_ == 1;
> Win32::Daemon::State (@_) unless CMDLINE ();
> $save_state = shift;
> return $save_state;
> }
>
> One last thought: You might think about logging to a file, so you can
> tell what your service is doing.
>
> Tom Wyant


Similar ThreadsPosted
SOAP::Lite services fault processing March 7, 2007, 12:22 pm
Windows: Perl:XS July 6, 2005, 4:57 am
Perl on Windows April 18, 2007, 3:30 pm
Imlib2 and Windows perl March 17, 2005, 6:28 am
Windows: Perl:Inline July 6, 2005, 4:56 am
help on how to use PERL to do a "postmessage" to a windows handle January 16, 2005, 12:10 pm
Installing Perl InlineC module in Windows 2003 August 4, 2005, 9:11 pm
Where to get DBD::pg for Windows? January 12, 2005, 1:02 pm
Net::SFTP on Windows March 21, 2005, 9:55 pm
Termcap under Windows XP... May 23, 2006, 1:49 pm

Our other projects:

Art Dolls, Fairies and Mermaids - Sunnyfaces.net

Roy's Linux, Programming and Search Engines messages

1-Script XML SitemapXML Sitemap