Windows Server Hack [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Windows Server Hack [Electronic resources] - نسخه متنی

Mitch Tulloch

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید
















Hack 5 Wait for and Optionally Terminate a Process







If you've wondered how to
write code that waits for a process to finish before terminating it,
here's the answer.



I have seen a number of discussions regarding the need for a VB
script that waits for a process to finish. The script in this hack
does this and more: it waits for a process to finish and optionally
terminates the process if it has not finished within a specified
amount of time.



This code is a modified form of what I use to control my software
deployments, and it has two purposes. First, the code is designed to
be certain that the deployment script waits until the initiated
software setup executable is fully finished before proceeding. Even
though the majority of recent software releases do not require this
functionality when being deployed, it is still required for some
legacy installations. Second, the code can perform a forceful
termination of an application if this functionality is required.



This script accepts three arguments: the name of the executable to
wait for or terminate, the amount of time to wait before terminating
the specified executable, and (optionally) a switch specifying that
the script should run silently. Note that the script uses Windows
Management Instrumentation (WMI) for the process-management tasks, so
make sure you're running the latest WMI version on
your machine.




The Code






The script consists of several sections, which are described inline
in the following sections.



Main routine






First, command-line switches are read in the main body area:



Option Explicit
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'
' File: vbsWaitForProcess.vbs
' Updated: Nov 2002
' Version: 1.0
' Author: Dan Thomson, myITforum.com columnist
' I can be contacted at dethomson@hotmail.com
'
' Usage: The command processor version must be run using cscript
' cscript vbsWaitForProcess.vbs notepad.exe 60 S
' or
' The IE and Popup versions can be run with cscript or wscript
' wscript vbsWaitForProcess.vbs notepad.exe -1
'
' Input: Name of executable (ex: notepad.exe)
' Time to wait in seconds before terminating the executable
' -1 waits indefinitely for the process to finish
' 0 terminates the process imediately
' Any value > 0 will cause the script to wait the specified
' amount of time in seconds before terminating the process
' Silent mode (S)
'
' Notes:
'
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
On Error Resume Next
'Define some variables
Dim strProcess
Dim intWaitTime
Dim strSilent
'Get the command line arguments
strProcess = Wscript.Arguments.Item(0)
intWaitTime = CInt(Wscript.Arguments.Item(1))
strSilent = Wscript.Arguments.Item(2)
Call WaitForProcess (strProcess, intWaitTime, strSilent)

Check if process is running






Next, the ProcessIsRunning function determines if
a process is running:



'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'
' Function: ProcessIsRunning
'
' Purpose: Determine if a process is running
'
' Input: Name of process
'
' Output: True or False depending on if the process is running
'
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Private Function ProcessIsRunning( strProcess )
Dim colProcessList
Set colProcessList = Getobject("Winmgmts:").Execquery _
("Select * from Win32_Process Where Name ='" & strProcess & "'")
If colProcessList.Count > 0 Then
ProcessIsRunning = True
Else
ProcessIsRunning = False
End If
Set colProcessList = Nothing
End Function

Terminate the process






In the next section, the ProcessTerminate function
terminates a process:



'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'
' Function: TerminateProcess
'
' Purpose: Terminates a process
'
' Input: Name of process
'
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Private Function ProcessTerminate( strProcess )
Dim colProcessList, objProcess
Set colProcessList = GetObject("Winmgmts:").ExecQuery _
("Select * from Win32_Process Where Name ='" & strProcess & "'")
For Each objProcess in colProcessList
objProcess.Terminate( )
Next
Set colProcessList = Nothing
End Function

Wait for process to terminate






Finally, in the WaitForProcess subroutine, the
user interface is set up, the script waits while the process is
active, and the process termination is initiated. I created three
versions of the subroutine in an effort to demonstrate a few methods
for displaying status messages. For example, here's
how to display these messages using the command console:



'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'
' Sub: WaitForProcess
'
' Purpose: Waits for a process
'
' Input: Name of process
' Wait time in seconds before termination.
' -1 will cause the script to wait indefinitely
' 0 terminates the process imediately
' Any value > 0 will cause the script to wait the specified
' amount of time in seconds before terminating the process
' Display mode.
' Passing S will run the script silent and not show any prompts
'
' Output: On screen status
'
' Notes: The version echos user messages in the command window via StdOut
'
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Private Sub WaitForProcess( strProcess, intWaitTime, strMode )
If ProcessIsRunning(strProcess) Then
Dim StdOut
Dim w : w = 0
Dim strPrompt
Dim intPause : intPause = 1
If UCase(strMode) <> "S" Then
strPrompt = "Waiting for " & strProcess & " to finish."
Set StdOut = WScript.StdOut
StdOut.WriteLine "
StdOut.Write strPrompt
End If
'Loop while the process is running
Do While ProcessIsRunning(strProcess)
'Check to see if specified # of seconds have passed before terminating
'the process. If yes, then terminate the process
If w >= intWaitTime AND intWaitTime >= 0 Then
Call ProcessTerminate(strProcess)
Exit Do
End If
'If not running silent, post user messages
If UCase(strMode) <> "S" Then _
StdOut.Write "."
'Increment the seconds counter
w = w + intPause
'Pause
Wscript.Sleep(intPause * 1000)
Loop
If UCase(strMode) <> "S" Then
StdOut.WriteLine "
Set StdOut = Nothing
End If
End If
End Sub



The result is shown in Figure 1-8.




Figure 1-8. Status message displayed in command console




Alternatively, here's some code for displaying
status messages in Internet Explorer:



'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'
' Sub: WaitForProcess
'
' Purpose: Waits for a process
'
' Input: Name of process
' Wait time in seconds before termination.
' -1 will cause the script to wait indefinitely
' 0 terminates the process imediately
' Any value > 0 will cause the script to wait the specified
' amount of time in seconds before terminating the process
' Display mode.
' Passing S will run the script silent and not show any prompts
'
' Output: On screen status
'
' Notes: This version uses Internet Explorer for user messages
'
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Private Sub WaitForProcess( strProcess, intWaitTime, strMode )
If ProcessIsRunning(strProcess) Then
Dim objIntExplorer
Dim c : c = 0
Dim w : w = 0
Dim strPrompt
Dim intPause : intPause = 1
strPrompt = "Waiting for " & strProcess & " to finish."
'If not running silent, create reference to objIntExplorer
'This will be used for the user messages. Also set IE display attributes
If UCase(strMode) <> "S" Then
Set objIntExplorer = Wscript._
CreateObject("InternetExplorer.Application")
With objIntExplorer
.Navigate "about:blank"
.ToolBar = 0
.Menubar = 0 ' no menu
.StatusBar = 0
.Width=400
.Height = 80
.Left = 100
.Top = 100
.Document.Title = "WaitForProcess"
End With
'Wait for IE to finish
Do While (objIntExplorer.Busy)
Wscript.Sleep 200
Loop
'Show IE
objIntExplorer.Visible = 1
End If
Do While ProcessIsRunning(strProcess)
'Check to see if specified # of seconds have passed before terminating
'the process. If yes, then terminate the process
If w >= intWaitTime AND intWaitTime >= 0 Then
Call ProcessTerminate(strProcess)
Exit Do
End If
If UCase(strMode) <> "S" Then
objIntExplorer.Document.Body.InnerHTML = strPrompt & String(c, ".")
'Increment the counter.
'Reset the counter indicator if it's > 25 because
'we don't want it taking up a lot of screen space.
If c > 25 Then c = 1 Else c = c + 1
'Increment the seconds counter
w = w + intPause
End If
'Pause
Wscript.Sleep(intPause * 1000)
Loop
objIntExplorer.Quit( ) ' close Internet Explorer
Set objIntExplorer = Nothing ' release object reference
End If
End Sub



The resulting status message is shown in Figure 1-9.




Figure 1-9. Displaying status messages in Internet Explorer




Finally, here's code that uses the Popup method of
Windows Scripting Host for displaying status messages:



''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'
' Sub: WaitForProcess
'
' Purpose: Waits for a process
'
' Input: Name of process
' Wait time in seconds before termination.
' -1 will cause the script to wait indefinitely
' 0 terminates the process imediately
' Any value > 0 will cause the script to wait the specified '
' amount of time in seconds before terminating the process
' Display mode.
' Passing S will run the script silent and not show any prompts
'
' Output: On screen status
'
' Notes: This version uses WshShell.Popup for user messages
'
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Private Sub WaitForProcess( strProcess, intWaitTime, strMode )
If ProcessIsRunning(strProcess) Then
Dim objWshShell
Dim c : c = 0
Dim w : w = 0
Dim strPrompt
Dim intPopupTimer : intPopupTimer = 2
Dim intPause : intPause = 1
strPrompt = "Waiting for " & strProcess & " to finish."
'If not running silent, create reference to objWshShell
'This will be used for the user messages
If UCase(strMode) <> "S" Then _
Set objWshShell = CreateObject("WScript.Shell")
'Loop while the process is running
Do While ProcessIsRunning(strProcess)
'Check to see if specified # of seconds have passed before terminating
'the process. If yes, then terminate the process
If w >= intWaitTime AND intWaitTime >= 0 Then
Call ProcessTerminate(strProcess)
Exit Do
End If
'If not running silent, post user prompt
If UCase(strMode) <> "S" Then
objWshShell.Popup strPrompt & String(c, "."), intPopupTimer, _
"WaitForProcess", 64
'Increment the counter.
'Reset the counter indicator if it's > 25 because
'we don't want it taking up a lot of screen space.
If c > 25 Then c = 1 Else c = c + 1
End If
'Increment the seconds counter
w = w + intPause + intPopupTimer
'Pause
Wscript.Sleep(intPause * 1000)
Loop
Set objWshShell = Nothing
End If
End Sub



The resulting dialog box is shown in Figure 1-10.




Figure 1-10. Displaying status messages in a dialog box




Note that if you are assembling a standalone script, it should
contain sections 1, 2, 3, and one option from section 4. If you would
rather incorporate this code into your existing script, you need only
sections 2, 3, and one option from section 4. You'll
also need to add the call statement that is at the end of the main
routine section. All the code sections are self-contained, which
makes them easy to import into existing scripts.




Running the Hack






To use this hack, type the code into Notepad (with Word Wrap
disabled) and save it with a .vbs extension as
WaitForProcess.vbs. Or, if you
don't want to tire your fingers out, download it
from the O'Reilly web site instead.



Here are a few sample command-line examples. This will wait
indefinitely until Notepad is closed:



cscript WaitForProcess.vbs notepad.exe -1



This will wait silently and indefinitely until Notepad is closed:



cscript WaitForProcess.vbs notepad.exe -1 S



And this will wait 10 seconds before Notepad is forcefully closed:



cscript WaitForProcess.vbs notepad.exe 10



Dan Thomson




/ 163