The "ServiceInstall" Command |
This command is used to install a service (it populates the MSI "ServiceInstall" table). You may also wish to use the "ServiceControl" command to manipulate the service (stop/start etc).
The service executable is indirectly specified as it is the keypath of the component associated with this entry.
You should also have a look at the "service tips" section of this manual.
Main Service Related Options |
Please see the "options for commands" section of the manual.
#define? DEFAULT_SERVICE_CONTROL_INSTALL_EVENTS STOP START #define? DEFAULT_SERVICE_CONTROL_UNINSTALL_EVENTS STOP DELETE #define? DEFAULT_SERVICE_INSTALL_PROCESS OWN #define? DEFAULT_SERVICE_INSTALL_START AUTO #define? DEFAULT_SERVICE_INSTALL_ERRORS NORMAL VITAL
The Parameters |
This command takes these parameters:
See the "ServiceInstall" table documentation for more details.
The default for this parameter can be set via the DEFAULT_SERVICE_INSTALL_PROCESS macro. The initial value is "OWN".
See the "ServiceInstall" table documentation for more details.
The default for this parameter can be set via the DEFAULT_SERVICE_INSTALL_START macro. The initial value is "AUTO".
See the "ServiceInstall" table documentation for more details.
The default for this parameter can be set via the DEFAULT_SERVICE_INSTALL_ERRORS macro. The initial value is "NORMAL VITAL".
Windows Installer (stupidly) doesnt' grant "SeServiceLogonRight" priviledges to the user, if the user doesn't already have these then the service won't start.
Note that the keypath of this component must be the service EXE!
Windows Installer Support is "Feeble" |
You may wish or need to use other tools or mechanisms to help set up a service such as (not a complete list):
EXAMPLE |
You should note that nearly all of the following code is to set up the optional recovery information.
;---------------------------------------------------------------------------- ;--- Some service constants ------------------------------------------------- ;---------------------------------------------------------------------------- #define MyServiceAlias MyService #define MyServiceDesc My Test Service (<$MSI_MSIBASENAME>) #define RecoveryResetInSeconds <?=6*60*60> ;;6 hours #( '/' #define RecoveryActions restart/5000 ;;1. Restart after 5 seconds restart/60000 ;;2. Restart after 1 minute restart/600000 ;;3+. Restart after 10 minutes #) ;---------------------------------------------------------------------------- ;--- Add service ------------------------------------------------------------ ;---------------------------------------------------------------------------- <$DirectoryTree Key="INSTALLDIR" Dir="[ProgramFilesFolder]\MyServiceDirectory" CHANGE="\"> <$Component "<$MyServiceAlias>" Create="Y" Directory_="INSTALLDIR"> ;--- The service EXE MUST be the keypath of the component ---------------- <$Files ".\MyService.EXE" KeyFile="*"> ;--- Create the service (service EXE is "KeyPath" of component) ---------- #( <$ServiceInstall Name="<$MyServiceAlias>" DisplayName="<$MyServiceDesc>" Description="<$MyServiceDesc>" Process="Own Interactive" > #) ;--- Control the service ------------------------------------------------- <$ServiceControl Name="<$MyServiceAlias>" AtInstall="start stop" AtUninstall="stop delete"> <$/Component> ;---------------------------------------------------------------------------- ;--- Need sc.exe available at install time (the CA below uses it) ----------- ;---------------------------------------------------------------------------- <$Component "ServiceTool" Create="Y" Directory_="INSTALLDIR"> <$Files ".\sc.exe" Comment=^This tool is used to set the services recovery options.^> <$/Component> ;---------------------------------------------------------------------------- ;--- Create script to execute "sc.exe" to set recovery options -------------- ;---------------------------------------------------------------------------- #data "CaData" "INSTALLDIR" '[INSTALLDIR]' #data <$VbsCa Binary="SetServiceRecovery.vbs" DATA=^CaData^> ;--- INSTALL ------------------------------------------------------------- <$VbsCaEntry "JustBeforeStartServices"> ;--- Call generic set recovery routine ------------------------------ SetRecovery "<$MyServiceAlias>", <$RecoveryResetInSeconds>, "<$RecoveryActions>" <$/VbsCaEntry> <?NewLine><?NewLine> '========================================= sub SetRecovery(ByVal ServiceAlias, ByVal RecoveryResetInSeconds, ByVal RecoveryActions) '========================================= ;--- Initialization -------------------------------------------------- CaDebug 1, "Set service recovery for """ & ServiceAlias & """" VbsCaLogInc 1 dim ScExe : ScExe = VbsCaCadGet("INSTALLDIR") & "sc.exe" dim ScArgs : ScArgs = "failure """ & ServiceAlias & """ reset= " & RecoveryResetInSeconds & " actions= " & RecoveryActions dim ScArgsQ : ScArgsQ = "qfailure """ & ServiceAlias & """" ;--- Set the recovery information ------------------------------------ CaDebug 2, "Setting up the services recovery options" VbsCaRunSync """" & ScExe & """ " & ScArgs, 0, "" ;;Ignore RC (can't be trusted) ;--- Log the current state of the recovery options ------------------- CaDebug 2, "Logging the services recovery options" VbsCaRunSync """" & ScExe & """ " & ScArgsQ, 0, "" ;--- Finished this service ------------------------------------------- VbsCaLogInc -1 end sub <$/VbsCa> ;---------------------------------------------------------------------------- ;--- Call the above script during install and uninstall (schedule them) ----- ;---------------------------------------------------------------------------- <$VbsCaSetup Binary="SetServiceRecovery.vbs" Entry="JustBeforeStartServices" Seq="InstallServices-" CONDITION=^<$CONDITION_INSTALL_ONLY>^ DATA=^CaData^>
EXAMPLE - Complete script to run VBSCRIPT |
The following script is complete but won't work unless you supply the files for the "SC.EXE" and "SrvStart.EXE" tools.
;---------------------------------------------------------------------------- ; MODULE NAME: VbscriptBasedService.MM ; ; $Author: USER "Dennis" $ ; $Revision: 1.5 $ ; $Date: 30 May 2009 15:07:16 $ ; $Logfile: C:/DBAREIS/Projects.PVCS/Win32/MakeMsi/VbscriptBasedService.MM.pvcs $ ; COPYRIGHT: (C)opyright Dennis Bareis, Australia, 2003 ; All rights reserved. ; ; DESCRIPTION ; ~~~~~~~~~~~ ; Installs a Windows service which is a VBSCRIPT. You must supply the tools ; pointed to by the "SOURCEDIR_SC.EXE" & "SOURCEDIR_SRVSTART_FILES" macros. ; ; I highly recommend that you log progress so you can easly debug issues. ; ; If you output to the console it makes it easier to debug (set the ; service to be interactive). You can also test the script like any other ; script. You may wish to define a "test mode" to shorten or remove delays ; while testing. ; ; If you are running the VBSCRIPT like a schedule (but probably running at ; random times with possibly random delays) you should make sure that ; a trap in your code doesn't cause the "sleep" to be bypassed or a ; lot of CPU could be consumed... ; If you have a process which doesn't exit then if it traps, again I'd ; be sure to catch it and add some delay before restarting. ; ; I like the idea of a script at least exiting occassionally to eliminate ; the danger of a memory leak. If you can't do this then I'd monitor memory ; usage over an extended period of time! ;---------------------------------------------------------------------------- ;--- Load MAKEMSI (via wrapper) --------------------------------------------- #include "ME.MMH" ;--- Create INSTALLDIR ------------------------------------------------------ <$DirectoryTree Key="INSTALLDIR" Dir="c:\program files\<$ProdInfo.ProductName>" CHANGE="\" PrimaryFolder="Y"> ;---------------------------------------------------------------------------- ;--- Install the SERVICE ---------------------------------------------------- ;---------------------------------------------------------------------------- #define SERVICE_NAME <$ProdInfo.ProductName> #define SERVICE_DESC My VBSCRIPT based service #define SERVICE_VBS_BASENAME MyServiceVbs.VBS #define SERVICE_VBS_IN_LOGDIR <$MAKEMSI_VBSCRIPT_DIR>\<$SERVICE_VBS_BASENAME> #define SOURCEDIR_SC.EXE .\ ;;In current directory #define SOURCEDIR_SRVSTART_FILES srvstart.exe\ <$FileMake "<$SERVICE_VBS_IN_LOGDIR>"> ;--- Require Variables to be defined and check generated syntax --------- option explicit <?SyntaxCheck> ;--- This service is a bit like a schedule, does some work then pauses --- DoStuff() ;;Even on trap MUST do pause (below) - could do it first! '--- Delays between invokations ------------------------------------------- wscript.echo "sleeping for 30 minutes..." ;;Only visible if service "interactive" (good idea to log) wscript.sleep 30 * (60 * 1000) ;;Sleep for 30 minutes wscript.quit 0 ;;srvstart.exe will now restart cscript and this service VBS <?NewLine><?NewLine> '=========================================================== sub DoStuff() ' ' This is called roughly every 30 minutes to do some work. '=========================================================== '--- Does something --- on error resume next end sub <$/FileMake> #( ;--- Simple macro to create component and add file ---------------------- #define ServiceNeeds #evaluate+ ^ItsShortName^ ^FilePart('NAME', '{$Source}')^ <$Component "VbsServiceNeeds_<$ItsShortName>" Create="Y" Directory_="INSTALLDIR"> <$File Source="{$Source}" Comment=~{$Comment}~ KeyPath="Y"> <$/Component> #) <$Component "Service" Create="Y" Directory_="INSTALLDIR"> ;--- Add the service EXE ------------------------------------------------- <$File KeyPath="Y" Source="<$SOURCEDIR_SRVSTART_FILES>srvstart.exe" Comment='Used to allow VBS to be used as a service (The Windows service manager directly executes this EXE).'> <$ServiceNeeds Source="<$SOURCEDIR_SRVSTART_FILES>srvstart.dll" Comment='Required by "srvstart.exe".'> <$ServiceNeeds Source="<$SOURCEDIR_SRVSTART_FILES>logger.dll" Comment='Required by "srvstart.exe".'> <$ServiceNeeds Source="<$SOURCEDIR_SC.EXE>sc.exe" Comment=^This tool is used to set the services recovery options.^> <$ServiceNeeds Source="<$SERVICE_VBS_IN_LOGDIR>" Comment=^"srvstart.exe" runs this VBS (its the service's code). Its main task is to collects MSI logs into a single directory.^> ;--- Set up the "srvstart.ini" file (pick your own options from doco) ---- <$IniFile "srvstart.ini" DIR="INSTALLDIR"> <$IniSection "<$SERVICE_NAME>"> ;--- What what and what current directory ------------------------ <$Ini "startup" Value=^"[SystemFolder]cscript.exe" //nologo //T:3600 "<$SERVICE_VBS_BASENAME>" "AnyParameter1" "AnyParameter2Etc"^> <$Ini "startup_dir" Value="[INSTALLDIR]"> ;;Don't quote dir! ;--- Set debug level to off/minimal, log to file not NT Event Log --- <$Ini "debug" Value="0"> ;;Minimal debug output <$Ini "debug_out" Value="[INSTALLDIR]<$SERVICE_NAME>(Service).LOG"> ;;Log to file (not NT Event Log!) ;--- Process priority (not many options..., tools source is available...) --- <$Ini "priority" Value="idle"> ;;Run the task at lowest priority ;--- Other options ----------------------------------------------- <$Ini "auto_restart" Value="Y"> ;;VBS will stop when finished! <$Ini "shutdown_method" Value="kill"> ;;How to terminate CSCRIPT.EXE <$Ini "restart_interval" Value="2"> ;;Workaround to SVRSTART.EXE (can't stop service) bug (VBS sleeps to cause delay) <$/IniSection> <$/IniFile> ;--- Install the service ------------------------------------------------- #( #define SVRSTART.EXE_PARMS ;--- Set debug level to zero to prevent 2 event log messages! -------- -d 0 ;--- Set configuration file (created above) -------------------------- -c "[INSTALLDIR]srvstart.ini" #) #( <$ServiceInstall Arguments=^svc <$SERVICE_NAME> <$SVRSTART.EXE_PARMS>^ Name="<$SERVICE_NAME>" DisplayName="<$SERVICE_NAME>" Description="<$SERVICE_DESC>" Process="Own" > #) ;--- Control the service (delete on uninstall) --------------------------- #( <$ServiceControl Name="<$SERVICE_NAME>" AtInstall="start stop" AtUninstall="stop delete" > #) ;--- Set recovery Options ------------------------------------------------ #data "CaData_INSTALLDIR" "INSTALLDIR" '[INSTALLDIR]' #data #define RecoveryResetInSeconds 300 #( '/' #define RecoveryActions ;--- Note that GUI won't display these correctly (its limited) ------- restart/60000 ;;1. Restart after 1 minute restart/300000 ;;2. Restart after 5 minutes restart/600000 ;;3+. Restart after 10 minutes #) <$VbsCa Binary="SetServiceRecovery.vbs" DATA=^CaData_INSTALLDIR^> ;--- INSTALL ------------------------------------------------------------- <$VbsCaEntry "JustBeforeStartServices"> ;--- Initialization -------------------------------------------------- dim ScExe : ScExe = VbsCaCadGet("INSTALLDIR") & "sc.exe" dim ScArgs : ScArgs = "failure <$SERVICE_NAME> reset= <$RecoveryResetInSeconds> actions= <$RecoveryActions>" dim ScArgsQ : ScArgsQ = "qfailure <$SERVICE_NAME>" ;--- Set the recovery information ------------------------------------ CaDebug 2, "Setting the control services recovery options" VbsCaRunSync """" & ScExe & """ " & ScArgs, 0, "" ;;Ignore RC (can't be trusted) ;--- Log the current state of the recovery options ------------------- CaDebug 2, "Logging the control services recovery options" VbsCaRunSync """" & ScExe & """ " & ScArgsQ, 0, "" <$/VbsCaEntry> <$/VbsCa> <$VbsCaSetup Binary="SetServiceRecovery.vbs" Entry="JustBeforeStartServices" Seq="<-StartServices" CONDITION=^<$CONDITION_EXCEPT_UNINSTALL>^ DATA=^CaData_INSTALLDIR^> <$/Component>