Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Run Scripts As Services - Exsead Service Manager

0.00/5 (No votes)
16 Feb 2007 1  
Exsead Service Manager is an Open Source (BSD Style License) Windows Service which launches anything via the use of scripts, it is just being released as Open Source, here is more about it.

Introduction

Exsead Service Manager Is An Open Source (BSD Style License) Windows Service Which Launches Anything Via The Use Of Scripts

In the Unix world, the equivalent of services are started using scripts. This makes life very simple indeed. If one wants to add in a background activity, one just adds in a launcher for it into one of these scripts. There is no requirement for a specially complied executable. In the Windows world, we choose to run executables directly off the Windows Service system. These executables must have a special interface compiled into them. Whilst this approach has its merits for many situations, it lacks flexibility and results in poor implementations such as using level 'Run' registry directives where services would be much more preferable.

The aim of Exsead Service Manager is to fit in as part of the entire Exsead concept: EXtreme Script Enterprise Application Development. In this case, the specific aim is to launch scripts as services. Once a service is scripted, you can do anything, easily!

Please help! ExseadServiceManager is now a Source Forge project. I am actively developing, but need help setting up the Source Forge SSH, CVS and Website.

If anyone is interested in helping with the project, please feel free to contact me at ajt(at)nerds-central.com. For now, the current release and source code can be found here. As I develop the product, I shall be placing new releases there. Keep an eye on Nerds-Central for news. The current version is in constant use by myself and I consider the core features to be beta for XP/SP2. Some of the features and for other operating systems, I would consider it to be alpha.

How Does ExseadServiceManager Actually Work?

The service manager itself is just a single executable. This executable installs, configures, uninstalls and runs the service. It differentiates which one is required of it by the way it is run and the nature of the command line arguments.

The steps to installing and using the service manager are as follows:

Naming the Service

Everything about ExseadServiceManager has been designed to be simple. I mean, a lot of thought was put into making using this application simple. Here is the first example. The name of the service it manages is controlled by the name of the executable. If you want to create a service called 'FlyingPigsNeedNappies' (diapers) then you make a copy of ExseadServiceManager.exe and rename it FlyingPigsNeedNappies.exe. It is that simple – really.

Where will it run?

When you install the service using the ExseadServiceManager, it sets the working directory of the service to the directory from which the installation was done. So, if you make a directory c:\FlyingPigs\Service and open a CMD box, change directory to c:\FlyingPigs\Service and run FlyingPigsNeedNappies.exe -I, then the service will run in c:\FlyingPigs\Service. Again – simple.

Install the Service

As it says above, you just run the executable with the -I option. This will make it run as local admin. If you use the -i option, then it will run as a different account.

Configuring the Service

The service can be configured, started, stopped and uninstalled from the command line options of the executable.

Connecting the Service to something

It is all very well setting up this service, but it has to do something. This is achieved by the script which has the same name as the executable but with the file extension vbs. For this version, only VBScript is supported for the initial script, but that should be addressed in later versions. So, in the flying pigs example, the initial script will have the name FlyingPigsNeedNappies.vbs. I'll discuss the structure of the initial script later in this post.

Where does the logging go?

The log for the service manager when running as a service goes to the default temp directory of the account that it is running as. For example, if it is running as Local Admin, then it will send the log to name.log in Windows\Temp. For the flying pigs example, it would be Windows\FlyingPigsNeedNappies.log. Please note that the amount of information sent to the log is small because the majority of the work in running the service is done by the initial script, not the service manager. Here is an example log output:

Service Main Called
Service Handler Acquired
Opening Service: 'TAGService'
Changing working dir to 'C:\CodeRepo\InfraStructure\InstallationAids'
About to run 'start'
Acquiring script object: TAGService.vbs
Acquired script object.
Loaded Script OK.

Here is the full list of command line options for the executable as written by running it with the -? option:

Exsead Service Manager: Command Line Args

  -? Print this message
  -r run start method directly avoiding service
  -e print out current env block
  -i 'user' 'pass' install service
  -I install service as local admin
  -u uninstall service
  -v print version info
  -s start service
  -k stop service
  -K first kill all descendants of the service process then stop service
  -Z  first kill all descendants of the process then kill it.
  -M set to manual start
  -A set to auto start
  -D set to disabled
  -S set to system start
  -B set to boot start

Notes: -K suspends the processes as it traverses the tree, but even with this
   level of checking, it might not get them all or it might kill a process
   that has just received the same pid as one that used to be a descendent.
   Please use this function with caution. This also applies to -Z.

Creating And Initial Service Script

At a minimum, the initial script must have two subroutines in it: StartService and StopService. Neither of these take any arguments.

StartService is called by the service manager when the service itself is started. This subroutine must initiate whatever the service does. When this subroutine exits, the service will stop. This means that if you want the service to stay running, you must not let this subroutine until the service is forced to stop. This can be done by an infinite loop, see the example below.

StopService is called by the service manager when the service is asked to stop by Windows. This can be initiated by running the executable with the -k option or using some other utility. StopService is called in a different thread of activity to start service, so it does not matter that StartService has not exited. In StopService, you must do whatever process shutdown and cleanup is required return.

Here is a real world initialize script which runs the TAGService for the TAG web application gateway:

Option Explicit

' Constants and identifiers
' =========================
CONST SERVICE_NAME = "TAGService"
CONST ForReading = 1, ForWriting = 2, ForAppending = 3

' Globals
' =======
Dim objWSHShell
Dim objWSHNetwork
Dim objFSO
Dim objLogger
Dim is_init

' This method ensures the globals are up
' but only creates the object (expensive)
' once.
sub init()
    if not is_init then
        Set objWSHShell   = CreateObject("WScript.Shell")
        Set objWSHNetwork = CreateObject("WScript.Network")
        Set objFSO        = CreateObject("Scripting.FileSystemObject")
        Set objLogger     = new Logger
        is_init=true
    end if
end sub      
    
class Logger

    private logFile 

    Private Sub Class_Initialize()
        set logFile=objFSO.openTextFile(SERVICE_NAME+"_script.log",ForWriting,true)
    End Sub

    public sub WriteLog(what)
        logFile.writeLine(what)
    end sub
    
    Private Sub Class_Terminate()
        logFile.close
    End Sub    

end class

sub StartService()
    init
    'objWSHShell.run SERVICE_NAME + ".exe -K"
    Dim curdir 
    dim tagFile
    curdir = objWSHShell.CurrentDirectory
    tagFile = curdir & "\..\CRI\bin\TAG_Runner.exe"
    If not objFSO.FileExists(tagFile) then
        SilentReport "Could not find " & tagFile, 0
        exit sub
    end if
    objWSHShell.CurrentDirectory=curdir +"\..\CRI\bin"
    while 1=1
        objWSHShell.run "TAG_Runner.exe",0,true
    wend
end sub

sub StopService()
    init
    ' Simply kill any running child processes of the script
    objWSHShell.run SERVICE_NAME + ".exe -K"
end sub

Sub SilentReport(sString, iErr)
    init
    objLogger.WriteLog(now & ": " & sString & " , " & iErr)    
End Sub

For more on this and other topics, please see Nerds-Central.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here