// This script demonstrates how to start a service from a Deferred Mode in System Context CA. // Technically, this can be run in immediate mode as well since it requires no access to the installer // state to execution, but in practice you must run as Deferred in System Context to have enough // rights to do so. var serviceName = "service_internal_name" var wmiRepository = null; var wmiServices = null; var resultEnumerator = null; var vsilService = null; var returnVal = 0; wmiRepository = GetObject("winmgmts:{impersonationLevel=impersonate}!\\\\.\\root\\cimv2"); wmiServices = wmiRepository.ExecQuery("Select * from Win32_Service Where Name = \"" +serviceName+ "\""); if (wmiServices != null) { if (wmiServices.Count > 0) { resultEnumerator = new Enumerator(wmiServices); try { vsilService = resultEnumerator.item(); if (vsilService.State == "Stopped") { LogMessage("Starting "+serviceName+"..."); returnVal = vsilService.StartService(); if (returnVal == 0) { LogMessage("Started service"); } else { if (returnVal == 2) LogMessage("Access denied starting service."); else LogMessage("Error "+returnVal+" starting service.") // Abort uninstall since service could not be stopped throw 3; } } else { LogMessage("Remote execution service not startable, state "+vsilService.State); } } catch (unexpectedException) { LogMessage("StopService: Error " +unexpectedException.number+ ": " +unexpectedException.message); // Rethrow to stop uninstall throw unexpectedException; } } } function LogMessage( messageString ) // Writes a line to the MSI log, or the console if running outside MSI. { var customActionName = "StartService"; if (DetectRunningInMSI()) { var msiMessageTypeInfo = 0x04000000 var logRecord = null; var currTime = new Date(); logRecord = Installer.CreateRecord(1); logRecord.StringData(0) = currTime.toTimeString() +" "+ customActionName +": [1]"; logRecord.StringData(1) = messageString; Session.Message(msiMessageTypeInfo, logRecord); logRecord = null; } else { var currTime = new Date(); messageString = currTime.toTimeString() +" "+ customActionName +": "+ messageString; WScript.Echo(messageString); } } function DetectRunningInMSI() // Returns TRUE if running in MSI, else FALSE { var returnVal = true; var stringVal = ""; try { // Try to reference the Session object, which is only provided by the MSI runtime engine stringVal = Session.Property("ProductCode"); } catch (thisException) { // An exception is only thrown if the runtime couldn't resolve Session, which means // this script is not running under MSI returnVal = false; } return returnVal; } |