Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Run a VBScript like a Windows Service... 1

Status
Not open for further replies.

FaneDuru

Technical User
Jul 15, 2002
141
RO
Is it possible to run a vbscript like a service without using Srvany.exe?
I mean I can create the service but when I try to start it I receive an error message (8). I can see the created service but when I manually try to start it "Error 193: 0xc1" appears... (is not a valid Win32 application). Since Srvany is able to solve that does anybody know how to solve the problem?

Code:
Const OWN_PROCESS = 16
Const NOT_INTERACTIVE = False
Const NORMAL_ERROR_CONTROL = 2
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set objService = objWMIService.Get("Win32_BaseService")
errReturn = objService.Create("StartService" ,"Personnel Database" , _
    "E:\VBScript\Test x\Start.vbs", OWN_PROCESS, NORMAL_ERROR_CONTROL, "Automatic", _
        NOT_INTERACTIVE, NULL, ""  )
if errReturn = 0 then
   wscript.Echo "Service created"
else
   Wscript.Echo "Error at creation: " & errReturn
end if

set objWMI = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
set objService = objWMI.Get("Win32_Service.Name='StartService'")
intRC = objService.StartService
if intRC > 0 then
 WScript.Echo "Error starting service: " & intRC
else
 WScript.Echo "Successfully started service"
end if

Fane Duru
 
SrvAny basically does it by being a proxie for the target application (i.e. a copy of SrvAny is actually the service that runs, and in turn it runs your application)

>I mean I can create the service

A service is significantly more complex than simply 'creating' it via WMI's BaseService object - and has a specific set of OS API calls that it needs to be able to respond to, something that VBS cannot do.

So no, without SrvAny (or a similar service-running proxie) you can't run a VBscript program as a service.
 
Thanks strongm!
Sorry for the delayed reply... You are fully right.
I tried to use srvAny in order to run a script like windows service. I used the next code and I have the service created, I can see it, start and stop it but the script does not do anything... Where am I wrong?

Code:
'Srvany.exe and Start.vbs must be in the same folder with this script !!!
'From Windows XP Cookbook !!!

Path=WScript.ScriptFullName
Nume = left(path,instrrev(path,"\"))

strComputer = "."
strSvcName = "ScriptStart"
strSrvAnyPath = Nume & "srvany.exe"
strVBScriptPath = "C:\WINDOWS\system32\wscript.exe"
strScript = Nume & "Start.vbs"

' ------ END CONFIGURATION ---------
const HKLM = &H80000002

' Service Type
Const KERNEL_DRIVER = 1
Const FS_DRIVER = 2
Const ADAPTER = 4
Const RECOGNIZER_DRIVER = 8
Const OWN_PROCESS = 16
Const SHARE_PROCESS = 32
Const INTERACTIVE_PROCESS = 256

INTERACT_WITH_DESKTOP = FALSE

' Error Control 
Const NOT_NOTIFIED = 0
Const USER_NOTIFIED = 1
Const SYSTEM_RESTARTED = 2
Const SYSTEM_STARTS = 3

Set ws = CreateObject("Wscript.Shell")

set objWMI = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
set objService = objWMI.Get("Win32_Service")
intRC = objService.Create(strSvcName,strSvcName,strSrvAnyPath, _ 
 OWN_PROCESS,SYSTEM_RESTARTED,"Automatic",INTERACT_WITH_DESKTOP, _
 "NT AUTHORITY\LocalService","")
if intRC > 0 then
 ws.PopUp "Error in service creating: " & intRC,5,"Prolbem...",48
 WScript.Quit
else
 ws.PopUp "service " & strSvcName & " successfully created!",5,"It goes...",64
end if

strKeyPath = "SYSTEM\CurrentControlSet\Services\" & _
 strSvcName & "\Parameters"
set objReg = GetObject("winmgmts:\\" & strComputer & "\root\default:StdRegProv")
  objReg.CreateKey HKLM,strKeyPath
  objReg.SetStringValue HKLM,strKeyPath,"Application",strVBScriptPath
  objReg.SetStringValue HKLM,strKeyPath,"AppParameters",strScript

Desc = "It does what is to be done..."
strKeyName = "SYSTEM\CurrentControlSet\Services\" &  strSvcName
  objReg.SetStringValue HKLM,strKeyName,"Description",Desc
  ws.PopUp "Createt the values in Registy",5,"Merge...",64

set objService = objWMI.Get("Win32_Service.Name='" & strSvcName & "'")
intRC = objService.StartService
if intRC > 0 then
 ws.PopUp "Error in starging the service: " & intRC,5,"Prolbem...",48
else
 ws.PopUp "Service " & strSvcName & " successfully started!",5,"Solved...",64
end if
Set ws=nothing: set objReg=nothing: set objService=nothing
Set objWMI=nothing

Thanks!
Fane Duru
 
Fane Duru,

I attempted to use the same code a few weeks ago but experienced a plethora of problems. In light, I wrote my own script that does things a little differently but gets the job done every time. I used psexec to install and register the service. Unfotunately, it MUST run in the forground because it issues key presses.

Here's my code. Feel free to adapt it to your needs. I hope it works for you.

Code:
'**************************
'DESCRIPTION:   Install a vbs script as a service on remote machine		|
'WRITTEN BY:    Daniel M. Jones
DATE:			August 3, 2009
DATE:	
*************************

'on error resume next

'**************************
 VARIABLE DEFINITION
'**************************

CONST HKLM = &H80000002
CONST SELF_VERSION = "0.1"
CONST SELF_SCRIPT  = "Install VBS Services"
CONST UNKNOWN = "Chickenless Soup"

dim strComputer
dim strSrvName
dim strSrvAnyPath
dim strTitle
dim strWScriptPath
dim strVBSScript

strLocalSrvAny   = "c:\windows\system32\services\srvany.exe"
strLocalInstSrv  = "c:\windows\system32\services\instsrv.exe"
strLocalReg      = "c:\windows\system32\services\profilescrubber\pssrv.reg"
strLocalVBS      = "c:\windows\system32\services\profilescrubber\pssrv.vbs"
strRemoteInstsrv = "\\server\instsrv.exe"
strRemoteSrvAny  = "\\server\srvany.exe"
strRemoteVBS     = "\\server\Profile Scrubber\pssrv.vbs"
strRemoteReg     = "\\server\Profile Scrubber\pssrv.reg"

strTitle = SELF_SCRIPT & " " & SELF_VERSION

set colServices = nothing
set objArgs     = Wscript.Arguments
set objFSO      = WScript.CreateObject("Scripting.FileSystemObject")
set objService  = nothing
set objShell    = WScript.CreateObject("WScript.Shell")
set objWMI      = nothing

'**************************
' FUNCTIONS
'**************************

function createDirectory (strDir)
	'msgbox "dir: " & strDir
	if (objFSO.FolderExists(strDir) = false) then
		strFile = right(strDir, len(strDir) - inStrRev(strDir, "\"))
		strParentDir = left(strDir, len(strDir) - len(strFile) - 1)
		if NOT (objFSO.FolderExists(strParentDir)) then createDirectory (strParentDir)
		if NOT (objFSO.FolderExists(strDir)) then objFSO.CreateFolder (strDir)
	end if
	'if (instr(strFile, ".") = 0) then objFSO.CreateFolder (strDir)
end function

sub sendk(strKeys)
    objShell.SendKeys strKeys
end sub

'**************************
' BEGIN
'**************************

strComputer = ucase(inputBox("Asset"))
strUNCComputer = "\\" & strComputer & "\c$"

set objWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
set colServices = objWMI.ExecQuery("Select * from Win32_Service")

for each objService in colServices
	if (objService.name = "Profile Scrubber") then objService.StopService() : wscript.sleep 3000
next

strUNCLocalSrvAny = replace(strLocalSrvAny, "c:", strUNCComputer)
strUNCLocalInstsrv = replace(strLocalInstsrv, "c:", strUNCComputer)
strUNCLocalVBS = replace(strLocalVBS, "c:", strUNCComputer)
strUNCLocalReg = replace(strLocalReg, "c:", strUNCComputer)

createDirectory (strUNCComputer & "\windows\system32\services\ProfileScrubber\")

objFSO.CopyFile strRemoteInstsrv, strUNCLocalInstsrv, true
objFSO.CopyFile strRemoteSrvAny, strUNCLocalSrvAny, true
objFSO.CopyFile strRemoteVBS, strUNCLocalVBS, true
objFSO.CopyFile strRemoteReg, strUNCLocalReg, true

objShell.Run "\\server\psexec \\" & strComputer & " cmd", 3, false

wscript.sleep 3000
sendk "cd \windows\system32\services{enter}"
wscript.sleep 500

sendk "instsrv ""Profile Scrubber"" c:\windows\system32\services\srvany.exe{enter}"
wscript.sleep 2000

sendk "reg import """ & strLocalReg & """{enter}"
wscript.sleep 2000

sendk "net start ""Profile Scrubber""{enter}"
wscript.sleep 3000

sendk "exit{enter}"
msgbox "Service installed"

The code from the XP Cookbook seems to properly provide the registery with service information. I exported the reg data to a file and used it as .reg file my code requires.

-Geates
 
Geates,

Firstly thanks for your prompt reply!
I try to install the service on local computer. I never used psexec. Does it work on local computer, too?

Fane Duru
 
I have run PsExec without remote computer name and it worked. I have adapted the code in the next way, the service has been created and started but the script still does not do anything... After creating the service must I do something else in order to make the script running?
Code:
'**************************
'DESCRIPTION:   Install a vbs script as a service on local machine        |
'WRITTEN BY:    Daniel M. Jones
'DATE:            August 3, 2009 - slightly adapted - September 2, 2009
'DATE:    *************************
'on error resume next

'************************** VARIABLE DEFINITION'**************************
CONST HKLM = &H80000002
CONST SELF_VERSION = "0.1"
CONST SELF_SCRIPT  = "Install VBS Services"
CONST UNKNOWN = "Chickenless Soup"

dim strComputer
dim strSrvName
dim strSrvAnyPath
dim strTitle
dim strWScriptPath
dim strVBSScript

dim Path, Nume
dim strSvcName 

Path=WScript.ScriptFullName
Nume = left(path,instrrev(path,"\"))
Nume1=left(Nume,len(nume)-1)


strLocalSrvAny   = Nume & "srvany.exe" 'in the same folder with this script
strLocalInstSrv  = Nume & "instsrv.exe" 'in the same folder with this script

strLocalVBS      = Nume & "Start.vbs" 'in the same folder with this script

strVBScriptPath = "C:\WINDOWS\system32\wscript.exe"
strPsExec        = Nume & "psexec.exe" 'in the same folder with this script

strSvcName = "TestScriptService"

strTitle = SELF_SCRIPT & " " & SELF_VERSION

set colServices = nothing
set objArgs     = Wscript.Arguments
set objFSO      = WScript.CreateObject("Scripting.FileSystemObject")
set objService  = nothing
set objShell    = WScript.CreateObject("WScript.Shell")
set objWMI      = nothing

'**************************' FUNCTIONS'************************** - 39

sub sendk(strKeys)
    objShell.SendKeys strKeys
end sub

'**************************' BEGIN'**************************

strComputer = "."        
set objWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
set colServices = objWMI.ExecQuery("Select * from Win32_Service")

for each objService in colServices    
    if (objService.name = strSvcName) then objService.StopService() : wscript.sleep 3000
next

strUNCLocalSrvAny = strLocalSrvAny     
strUNCLocalInstsrv = strLocalInstsrv   
strUNCLocalVBS = strLocalVBS           

objShell.Run chr(34) & strPsExec & chr(34) & " cmd", 3, false
wscript.sleep 3000

sendk "cd " & Nume1 & "{enter}"
wscript.sleep 500

sendk "instsrv " & chr(34) & strSvcName & chr(34) & " " & chr(34) & Nume & "srvany.exe" & chr(34) & "{enter}"
wscript.sleep 2000

'sendk "reg import """ & strLocalReg & """{enter}"
'wscript.sleep 2000

'Registry part without .reg file...:
strKeyPath = "SYSTEM\CurrentControlSet\Services\" & _
 strSvcName & "\Parameters"
set objReg = GetObject("winmgmts:\\" & strComputer & "\root\default:StdRegProv")
  objReg.CreateKey HKLM,strKeyPath
  objReg.SetStringValue HKLM,strKeyPath,"Application",strVBScriptPath
  objReg.SetStringValue HKLM,strKeyPath,"AppParameters",strLocalVBS

Desc = "it does whatever..."
strKeyName = "SYSTEM\CurrentControlSet\Services\" &  strSvcName
  objReg.SetStringValue HKLM,strKeyName,"Description",Desc
  objShell.PopUp "Created values in Registy",5,"It works...",64
'____________________________

sendk "net start " & chr(34) & strSvcName & chr(34) & "{enter}"
wscript.sleep 3000

sendk "exit{enter}"

msgbox "Service installed"

Fane Duru
 
If you are trying to install the locally, you will not need PSExec. This program is used to run commands on a remote machine. But, as you have demetrated, it will work locally but is not needed. There are a few things you should check.

1) If the service is created successfully, double check the registry. There is a reg key ("ImagePath") of type REG_EXPAND_SZ that must be set correctly, other wise the service will no run.

2) The other issue could be start.vbs. Services are run in the background and do not interface with end user, therefore, you will not be notified by start.vbs when there is an error.

3) Check to see if both srvany.exe and wscript.exe are running in your process list. If you do not see wscript.exe, the registry my be misconfigured. If you do see it, start.vbs most likely has an error.

-Geates
 
The strange think is that I have checked all these issues and everything looks to be ok:
1) "ImagePath" keeps the right path to the script. When I check if "Start.vbs" is running the process is enumerated like running through wscript.exe. On the start sequence of the start.vbs it checks if another session is running and it looks that runs...
2) The script contains on purpose some PopUps in order to make me see that it works. Can that be a problem? Should I make it interactive process?
3) Both srvany.exe and wscript.exe are running in my process list. More then that wscript.exe is running start.vbs script. But the script does not do what is to be done...

What can be wrong?

Fane Duru
 
Supposing that the script is wrong I have replaced the original start.vbs with a simple one:
Code:
Dim objFSO:Set objFSO = CreateObject("Scripting.FileSystemObject")
Dim path, CreatedFile
Path=WScript.ScriptFullName
Path=left(path,instrrev(path,"\"))

CreatedFile = path&"Created_Test_"&day(now)&"_"&month(now)&"_"&year(now)&".log"

do

	If objFSO.FileExists(CreatedFile) = false Then
		Set Cr1 = objFso.OpenTextFile(CreatedFile, 8, True, -1) 'for appending
		    Cr1.Write "Y - Test"
		Cr1.close
        End if
loop

It does not work like service even it appears to be running. Srvany.exe is running, too...

Any help will be appreciated.
Thanks in advance,

Fane Duru
 
The code seems right. I bet anything the problem still lies in the registry.

I was able to install your code as a service on a remote machine. I zipped up the files and put them:


You will have to once again edit the code for your needs. As the code currently stands, when you are prompted by install.vbs, you can enter just a dot (.) to refer to the local machine.

-Geates

PS, if are implemented a vbs service contains a loop (and it does), I strongly recommend putting a delay in the loop (wscript.sleep 1000 'millisecs) to prevent the process from using ALL the computer resources.
 
Thanks Geates! I figured it out. You deserve a star...

Ping function in your script does not work with dot and path with double \\ does not work on local computer... I did it like in my previous code (based on yours).

It looks that being a windows service the necessary files must be located somewhere in Windows... I used the paths from your script and it worked. I did the same in the initial script form Windows XP Cookbook which worked, too. It was necessary only to change "NT AUTHORITY\LocalService" with Null in order to make the service to Log On as Local Service.

Fane Duru
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top