• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 992
  • Last Modified:

Restart a service when a programe Hangs

Hi all,

I am trying to restart a service if a particular command line program hangs / gives out error. The program, if successful will give out(into stdout )  "Host ....."

What i had come with is on the "code segment".
I use "Set objExecObject = objShell.Exec(strCommand)"  to call the program.
(Where strCommand in this case is err.exe which just prints the key word into the stdout/stderr . it prints "Error: asdfasf"  or "Host .................." . I edit the program and rebuild it every time as per the requirement. )

But the problem is, if the program(err.exe) hangs, it will not execute the next line rather it waits for the program finishes.

In reality the program i would be using is fusping (a Cyberfusion custom program  to test the server)

key word to look for = "Error :"
a reverse logic can be to look for the Keyword "Host"

if the program hangs : Nothing comes out. and waits

Can any one help me to bypass this issue.

OS : win 2k server ( I think it should work on any thing from win 2k / xp )
Option Explicit
Dim intShortSleep, intLongSleep, strService
dim objShell, objExecObject, strOutput
Dim strCommand
dim intFound
 
strService = "Messenger"  ' Messenger is just an example'
 
intShortSleep = 5000
intLongSleep = 15000  '1000 = 1 second '
strCommand = "err"  ' err is just an exe , made using a C program, in reality , it will be fusping of cyberfusion '
 
logExec (strCommand)
 
Msgbox intFound & "  Before the loop ... clear it " ' Just a message box to test the looping can ignore this'
Do Until  intFound =0
	Restart()
	Wscript.Sleep intLongSleep
	intFound=0
	logExec(strCommand)
	Msgbox intFound &  " Inthe loop ..Clear it"
	
loop
Msgbox "bye" ' Remove before implimentation'
 
Sub logExec(strCommand)
  
  
  Set objShell = WScript.CreateObject("WScript.Shell")
  Set objExecObject = objShell.Exec(strCommand)
  Do Until objExecObject.Stdout.AtEndOfStream
     strOutput = objExecObject.Stdout.ReadLine()
     ' syntax : InStr([start,]string1,string2[,compare])'
	 intFound=intFound + InStr(strOutput,"Error")
	
    
  loop
   strOutput=""
  end sub
 
Sub Restart()
' Restart Service'
objShell.Run "net stop " & strService
Wscript.Sleep intShortSleep
objShell.Run "net start " & strService
Wscript.Sleep intLongSleep
End Sub

Open in new window

0
Heins
Asked:
Heins
  • 3
  • 2
2 Solutions
 
HeinsAuthor Commented:
I think it deserves a higher point ...
0
 
jake072Commented:
Heins,

You are correct that the this program will never exit until the calling program is done it's execution.  If you have to log via std.out, then you are doing it correctly.  If the program hangs, however, you are right that it will never exit...  So, you need a way to monitor the execution time.  I would suggest creating a timer when you initially do the execute.  If the timer hits, and the loops hasn't existed, you should retry.

Let me know if you need more help,

Jake
0
 
HeinsAuthor Commented:
Dear Jake

Thanks a lot for the comment . I did think of this logic. But, since I am not that of an expert in scripting , can you throw some light on how to create a timer and start a different thread. What really happens is that , I am not sure, how to make the program counter to execute next line of code, when the execution previous one is not complete.

In addition, My understanding of script is that, it is like shell commands, which is executed line by line and not like a compilable program . it would be great, if you could give a small example to help me on this.

I looked into the "settimer" one but i thought that, it would work similar to sleep , but can just call a program or function when timer times out. If, in that case as well, the program does not execute next line.

But I know there should be some way as the scripts are supposed to handle this as a part of automation of human action.

Just to be more specific about the issue . In real time this is how manual method is   :

1 . In command prompt , navigate to the folder in which the "Program" (Fusping) exists.
2. run fusping as  fusping <serverHostname> in  most cases localhost.
3. it returns with the name of the host and status of the service along with name of the existing patch.
                           Or
  It returns an error saying "Error:" so and so service failed to respond or some thing like that.

4 . Irrespective of what ever error it is . stop / kill the services and wait for around 15 sec and start the service back again. 99.99% the service will run and everything will be fine.
5. to verify , run the fusping (step 1 & 2) again and make sure it returns no error.

whole these can be achieved by the above script with small modification. But on a worst case , which is 5-10 % of the cases , the program fusping itself hangs. ie. it comes up with neither error nor an output.  Fixing this is simple , terminate fusping and restart the services and eveything works fine.
   
Hope that would ring a bell in you to suggest me something to automate this. even ready to change the whole logic but just help me to achieve that . It had been a pain for a long time.
0
 
jake072Commented:
Heins,

What we need to do is to actually thread out the call to the following sub...

Sub logExec(strCommand)
 
 
  Set objShell = WScript.CreateObject("WScript.Shell")
  Set objExecObject = objShell.Exec(strCommand)
  Do Until objExecObject.Stdout.AtEndOfStream
     strOutput = objExecObject.Stdout.ReadLine()
     ' syntax : InStr([start,]string1,string2[,compare])'
         intFound=intFound + InStr(strOutput,"Error")
       
   
  loop
   strOutput=""
  end sub

Here is an example:

Dim t As Thread
t = New Thread(AddressOf logExec)
t.Start()

This will start your thread...  Now, if you are worried about that getting hung up, then add this:

Private t As Thread ' Module level variable !
Private WithEvents c As Timer ' Module level variable !

Sub:

t = New Thread(AddressOf logExec)
c = New Timer(15 * 1000) ' 15 seconds.
Addhandler c.Tick,AddressOf OnTimerEvent
c.Enabled = True
t.Start()

Public Shared Sub OnTimerEvent(ByVal [source] As Object, ByVal e As EventArgs)

' This will fire when 15 seconds has ellaped.  If the thread isn't done, then we need to kill it?
If t.IsAlive Then
   t.Stop ' Kill the tread

   ' Do other mantaince here...

End If

c.Enabled = False ' Cancel the timer.

End Sub 'OnTimerEvent

If you need more help, let me know,

Jake
0
 
HeinsAuthor Commented:
Jake ,

You are a genius , I will try it when i reach work and update you on the status .Thanks a lot for  the help. Before closing this question  i will update you about this for sure.
0

Featured Post

Microsoft Certification Exam 74-409

VeeamĀ® is happy to provide the Microsoft community with a study guide prepared by MVP and MCT, Orin Thomas. This guide will take you through each of the exam objectives, helping you to prepare for and pass the examination.

  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now