Steve

Steven K. Mariner

Last Updated: 04-Jun-2011

| Mariner Home | Steve | Kristie | Triona | Cressa | skmpu@bhmk.com |

| eBay | Programming | Wargaming | Music | RenFaire | Motorcycles | Fidonet | skmpu@bhmk.com |

Installing a Perl Script as a Windows Service

This is a step-by-step approach to installing a Perl script as a Service under Windows. This was formulated by reading a handful of web pages, with critical information obtained by dissecting jryan's Perl script at Perlmonks ( http://www.perlmonks.org/?node_id=230377 ).

Of course, being the Perl afficianado that you are, you've already gone to Perlmonks, right?

So -- You want to run a Perl script as a Windows Service.

In any regard, this page discusses one way to make that happen. For this technique, you'll need:

This should be deployable almost as is. About the only things you should need to change are references to where the Perl binary is located and which directory into which you drop all files from this example. I'm going to presume you can handle those things.

On all files noted here, global change and replace should be sufficient on these strings:

Without further adieu:

  1. I launched a Command Prompt window and created a directory to develop the script and supporting components:
     
     md C:\Steve\Dev\perlservice-perl 
     C: 
     cd \Steve\Dev\perlservice-perl 
     
  2. I wrote the Perl script. Its only purpose in Life is to confirm that the service actually ran the Perl script. It does this by appending a timestamped entry to a log file. Since log files are generally the only way to find out what a Service has been doing anyway, it is critical that the Perl script be able to do this. We also need to be able to find the resulting information afterwards. So, in essence, this steps knocks off a few elements of the learning curve all at once. Not only do we get to confirm the script was run by the sevice, but we also learn where log files end up by default.
     perlservicetest.pl :
    #!/usr/bin/perl
    
    my $statim = time;
    open LOGFIL, ">>perlservicetest.log";
    print LOGFIL "$statim perlservicetest START\n";
    close LOGFIL;
    
    exit;
    
    __END__
    
  3. I created a registry file to set the parameters needed to make the service run. This was based almost entirely on jryan's script at the start of the Perlmonks thread noted above.
     perlservicetest.reg :
    Windows Registry Editor Version 5.00
    
    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\perlservicetest\Parameters]
    "Application"="C:\\Perl\\bin\\perl.exe"
    "AppDirectory"="C:\\Steve\\Dev\\perlservice-perl"
    "AppParameters"="C:\\Steve\\Dev\\perlservice-perl\\perlservicetest.pl"
    
    
    (Don't forget the extra blank line at the end; it is not optional.)
    (Also -- where shown, the doubling of the backslashes are not optional.)
     
  4. I copied the  instsrv.exe  and  srvany.exe  files to the same directory as the Perl script. You'll need to find these; I believe they are commonly found on the Windows NT 4.0 Resource Kit, and also found somewhere on the default installation of Windows 2000 Server and Windows 2003 Server. I think I'd heard somewhere they might not be available on Windows Server 2008 but this is not confirmed as of this writing. As a note of last resort, searching for those executable filenames on any decent search engine should eventually yield results. I think there's a link or two in the Perlmonks thread mentioned at the top of this page.
     
  5. I created a batch file to install and start up the new service. However, we want to install to a clean slate. Therefore, it also ensures any old versions are first stopped and removed. If there is no previous version installed, these steps will produce warnings and errors, but that's okay. The only part that matters is that when we get to the installation step, it's installing cleanly. I leave it as an exercise for the reader to adjust this so it only does removal steps when needed, as that is outside the scope of this document.

     perlservicetest-install.bat :

    @echo off
    echo -------------------------------------------------------------------------------
    echo Checking logfile contents
    echo -------------------------------------------------------------------------------
    type perlservicetest.log
    pause
    echo -------------------------------------------------------------------------------
    echo Checking service status
    echo -------------------------------------------------------------------------------
    sc qc "perlservicetest"
    pause
    echo -------------------------------------------------------------------------------
    echo Stopping old service
    echo -------------------------------------------------------------------------------
    net stop perlservicetest
    pause
    echo -------------------------------------------------------------------------------
    echo Removing old service
    echo -------------------------------------------------------------------------------
    instsrv perlservicetest remove
    sc qc "perlservicetest"
    pause
    echo -------------------------------------------------------------------------------
    echo Installing new service
    echo -------------------------------------------------------------------------------
    instsrv perlservicetest C:\Steve\Dev\perlservice-perl\srvany.exe
    sc qc "perlservicetest"
    pause
    echo -------------------------------------------------------------------------------
    echo Modifying new service parameters
    echo -------------------------------------------------------------------------------
    REM start /WAIT "Registry Update" perlservicetest.reg
    regedit /s C:\Steve\Dev\perlservice-perl\perlservicetest.reg
    pause
    echo -------------------------------------------------------------------------------
    echo Starting new service
    echo -------------------------------------------------------------------------------
    net start perlservicetest
    pause
    echo -------------------------------------------------------------------------------
    echo Checking logfile contents
    echo -------------------------------------------------------------------------------
    type perlservicetest.log
    echo -------------------------------------------------------------------------------
    

Okay, so after tweeking and twiddling, I wound up with the above file sets and voila! I had a working Windows Service which ran a Perl script of my own creation.

Now we need to learn how to clean up after ourselves. So -- to remove the service:

  1. I created a registry file to remove the service configuration information. Note the use of the minus sign to remove parameters and keys from the registry. Technically, the approach below is probably redundant, since removal of the key will almost certainly remove subkeys as well as the parameters in those keys. However, I find symetry and reciprocity to be good Engineering practices, and I'm a bit pedantic about it. More to the point, however, this gives me a working example in the event I ever just need to remove a single parameter. When push comes to shove, I'll take a working example over time wasted on search engines any day of the week. This of course is mildly humorous as you probably found me via a search engine. :-)
     perlservicetest-delete.reg :
    Windows Registry Editor Version 5.00
    
    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\perlservicetest\Parameters]
    "Application"=-
    "AppDirectory"=-
    "AppParameters"=-
    
    [-HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\perlservicetest\Parameters]
    
    [-HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\perlservicetest]
    
    
    (Again, remember -- the extra blank line at the end is not optional.)
     
  2. I created a batch file to stop and remove the service.
     perlservicetest-uninstall.bat :
    @echo off
    echo -------------------------------------------------------------------------------
    echo Checking logfile contents
    echo -------------------------------------------------------------------------------
    type perlservicetest.log
    pause
    echo -------------------------------------------------------------------------------
    echo Checking service status
    echo -------------------------------------------------------------------------------
    sc qc "perlservicetest"
    pause
    echo -------------------------------------------------------------------------------
    echo Stopping old service
    echo -------------------------------------------------------------------------------
    net stop perlservicetest
    pause
    echo -------------------------------------------------------------------------------
    echo Removing old service
    echo -------------------------------------------------------------------------------
    instsrv perlservicetest remove
    sc qc "perlservicetest"
    pause
    echo -------------------------------------------------------------------------------
    echo Removing service parameters
    echo -------------------------------------------------------------------------------
    regedit /s C:\Steve\Dev\perlservice-perl\perlservicetest-delete.reg
    echo -------------------------------------------------------------------------------
    

So, if you initially deploy this on your system, as is, changing only the items noted at the top of this page, it should work. That gives you a functioning baseline from which to begin your journey.

Once you have a functioning Windows Service Perl script, you can adjust individual components to customize it to your needs. Maybe you want  instsrv.exe  and  srvany.exe  to live somewhere common. Maybe you want to change the service name from  perlservicetest . Maybe you want the Perl script to do more than write lines to a log file.

If the change you make doesn't give you the results you are looking for, roll back to the last one that worked, and keep chiseling away at it, back and forth, until you have molded it into your personal Windows Service masterpiece.

:-)

| eBay | Programming | Wargaming | Music | RenFaire | Motorcycles | Fidonet | skmpu@bhmk.com |

| Mariner Home | Steve | Kristie | Triona | Cressa | skmpu@bhmk.com |

© 2011, Steven K. Mariner