Hello all. When creating scripts, I've made it a practice to set
objects to nothing as the script closes in order to free memory
resources. But what happens when you've got a script that is running as
a Windows Service (SRVANY.EXE)?

In my script I've got a "Do While" Loop that repeats every 15 minutes
(Wscript.Sleep 900000) . So the script will keep running indefinitely
until I stop the Windows Service. But when I do stop the service, the
commands that set objects to nothing won't execute - since they are
outside of the "Do While" Loop. What to do?

Here's the script:
(watch for word wrap)

...

Const HKEY_LOCAL_MACHINE = &H80000002
Const ForReading = 1, ForWriting = 2, ForAppending = 8
Const OverwriteExisting = True
Const OverWriteFiles = True

Set objShell = CreateObject("WScript.Shell")
Set objFSO = CreateObject("Scripting.FileSystemObject")

Dim strCRI, Today, mm, dd, hh, mn, TimeStamp, LogFolder
Dim Servers, List, strComputer
Dim strKeyPath, strEntryName, IsOnline, Timeout
Dim LogFile, UsersVal, Threshold, AlertLog, FlagFile, Increased
Dim strSubj, strContents, SendTo1, SendTo2, SendTo3, SendTo4, SendTo

Dim CurDir
CurDir = objFSO.GetFolder(".").Path
Set Folder = objFSO.GetFolder(CurDir)

'~~~ Repeat the subroutine Query every 15 minutes.
'~~~ At midnight run the subroutine RemoveFolders to
'~~~ delete the previous day's folders.
Do While ScriptFinish <> True
IF Hour(Now) = 0 Then
RemoveFolders
End IF
Query
Wscript.Sleep 900000
Loop

Sub Query
If WeekDay(Now) = "1" Then Today = "Sun"
If WeekDay(Now) = "2" Then Today = "Mon"
If WeekDay(Now) = "3" Then Today = "Tue"
If WeekDay(Now) = "4" Then Today = "Wed"
If WeekDay(Now) = "5" Then Today = "Thu"
If WeekDay(Now) = "6" Then Today = "Fri"
If WeekDay(Now) = "7" Then Today = "Sat"
mm = Right("00" & Month(Now), 2)
dd = Right("00" & Day(Now), 2)
hh = Right("00" & Hour(Now), 2)
mn = Right("00" & Minute(Now), 2)
TimeStamp = Today & "_" & mm & "_" & dd & "___" & hh & "-" & mn

'~~~ Create a log folder to store the results of each query.
LogFolder = Today & "___" & hh & "_" & mn
IF NOT objFSO.FolderExists(LogFolder) Then _
objFSO.CreateFolder(LogFolder)

List = "List.txt"
Set ListFile = objFSO.OpenTextFile(List, 1)

Do Until ListFile.AtEndOfStream
strComputer = ListFile.ReadLine

'~~~ Use a flag file to indicate that a server has already exceeded
'~~~ the (number of users) threshold and triggered the alert.
FlagFile = CurDir & "\Flags\" & strComputer & ".txt"

'~~~ Check Registry to see if server is on the Farm.
On Error Resume Next
Set objReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" &
_
strComputer & "\root\default:StdRegProv")

strKeyPath = "SOFTWARE\AppServers\HealthCheck"
strEntryName = "IsOnline"
objReg.GetDWORDValue
HKEY_LOCAL_MACHINE,strKeyPath,strEntryName,dwValue
IsOnline = dwValue

'~~~ Delete any previous flag files if the server is no longer on
the Farm.
IF NOT IsOnline = 1 Then
IF objFSO.FileExists(FlagFile) Then objFSO.DeleteFile(FlagFile)
Else
'~~~ Check Registry for the "Timeout" value to see if server is at
"Reset" status
strEntryName = "Timeout"
objReg.GetDWORDValue
HKEY_LOCAL_MACHINE,strKeyPath,strEntryName,dwValue
Timeout = dwValue

Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer &
"\root\cimv2")
Set colItems = objWMIService.ExecQuery _
("Select * from Win32_PerfRawData_W3SVC_WebService where
Name='Default Web Site'")
For Each objItem in colItems
Users = objItem.CurrentAnonymousUsers
Next
On Error GoTo 0

'~~~ Write the results of the number of users query to a log file.
LogFile = LogFolder & "\" & strComputer & ".txt"
Set f = objFSO.OpenTextFile (LogFile,8,True)
f.writeline Users
f.close

'~~~ Read each server's log file, and if it has exceeded
'~~~ the (number of users) threshold then trigger the alert.
Set BoxLog = objFSO.OpenTextFile(LogFile, 1)
UsersVal = BoxLog.ReadLine
UsersVal = CInt(UsersVal)
Threshold = 900

'~~~ If the "Timeout" registry value is anything other than 0,
'~~~ then that server is at "Reset" status and will be skipped.
'~~~ Otherwise run the threshold comparison.
IF Timeout = 0 Then
IF UsersVal > Threshold Then
TriggerAlert strComputer, UsersVal
End IF
END IF
BoxLog.close
End IF ' IsOnline = 1
Loop ' Do Until ListFile.AtEndOfStream
ListFile.close
End Sub ' Query

Function TriggerAlert(strComputer,UsersVal)
AlertLog = "D:\Tasks\Anonymous_Users_Alert__" & TimeStamp & "_.txt"

'~~~ If it's non-business hours or weekends, write to the
'~~~ Alert log file only; otherwise write to the Alert log file
'~~~ AND send a message (e-mails and SKYTEL pages).
IF Weekday(Now) mod 7 < 2 Or Hour(Now) mod 18 < 9 Then
AlertLogWrite AlertLog, strComputer, UsersVal
Else
'~~~ If flag file exists write to the Alert log file only.
IF objFSO.FileExists(FlagFile) Then
AlertLogWrite AlertLog, strComputer, UsersVal
Else
AlertLogWrite AlertLog, strComputer, UsersVal

strSubj = "...Excessive Number of Users on " & strComputer & "."
strContents = "There are " & UsersVal & " users on " & strComputer
SendTo1 = "drmfs@mycompany.com; 1248627@skytel.com; "
SendTo2 = "gwila@mycompany.com; 1958471@skytel.com; "
SendTo3 = "torfn@mycompany.com; 1125698@skytel.com; "
SendTo4 = "dbron@mycompany.com; NYCtech@mycompany.com"
SendTo = SendTo1 & SendTo2 & SendTo3 & SendTo4
Send_Message SendTo

'~~~ Create the flag file.
Set objFlag = objFSO.OpenTextFile(FlagFile, 2, True, 0)
objFlag.WriteLine UsersVal
objFlag.Close
End IF ' objFSO.FileExists(FlagFile)
End IF ' Weekday(Now)
End Function ' TriggerAlert

Function AlertLogWrite(AlertLog,strComputer,UsersVal)
Set objAlertLog = objFSO.OpenTextFile(AlertLog, 8, True, 0)
objAlertLog.WriteLine strComputer & vbTab & UsersVal & VbCrlf
objAlertLog.Close
End Function

Sub Send_Message (sendTo)
sch = "http://schemas.microsoft.com/cdo/configuration/"
Set cdoConfig = CreateObject("CDO.Configuration")
With cdoConfig.Fields
.Item(sch & "sendusing") = 2 ' cdoSendUsingPort
.Item(sch & "smtpserver") = "mail.mycompany.com"
'.Item(sch & "smtpserverport") = 25 ' if you need to set a port
number
.update
End With

Set cdoMessage = CreateObject ("CDO.Message")
With cdoMessage
Set .Configuration = cdoConfig
.From = "Alerts-@mycompany.com"
.To = sendTo
.Subject = strSubj
.TextBody = strContents
.Send
End With
Set cdoConfig = nothing
Set cdoMessage = nothing
End Sub ' Send_Message

Sub RemoveFolders
'~~~ Delete (the previous day's folders) all folders which
'~~~ have three underscores in the folder name.
strCRI ="___"
For Each subfolder In Folder.Subfolders
IF Instr(subfolder.name, strCRI) Then
s = Subfolder.path
objShell.Run "%comspec% /c RD /S /Q " & s, 0
End IF
Next
Wscript.Sleep 1800000
End Sub

Set objShell = nothing
Set objFSO = nothing
Set Folder = nothing
Set ListFile = nothing
Set objReg = nothing
Set objWMIService = nothing
Set colSettings = nothing
Set f = nothing
Set BoxLog = nothing
Set objFlag = nothing
Set objAlertLog = nothing

Re: The necessity of Setting Objects to Nothing by Anthony

Anthony
Fri May 12 13:51:45 CDT 2006


"Highlander" <tron9901@msn.com> wrote in message
news:1147446470.966295.258350@u72g2000cwu.googlegroups.com...
> Hello all. When creating scripts, I've made it a practice to set
> objects to nothing as the script closes in order to free memory
> resources. But what happens when you've got a script that is running as
> a Windows Service (SRVANY.EXE)?
>
> In my script I've got a "Do While" Loop that repeats every 15 minutes
> (Wscript.Sleep 900000) . So the script will keep running indefinitely
> until I stop the Windows Service. But when I do stop the service, the
> commands that set objects to nothing won't execute - since they are
> outside of the "Do While" Loop. What to do?
>

A few things.

If it's a service and the service it stopped then the process running the
service is shutdown. It's doesn't matter how badly you code there no memory
allocation survives the destruction of the process.

If you have objects holding on to significant resources or holding things
open that don't need to be open during the 15 Minute interval between runs
then you should release them from inside your outer loop.

Setting all these objects to nothing at the bottom of your script is a waste
of time anyway. The script engine will release them for you. Anything you
have heard to the contrary is simply FUD.

Anthony.




Re: The necessity of Setting Objects to Nothing by Bob

Bob
Fri May 12 14:23:43 CDT 2006

Anthony Jones wrote:
>
> Setting all these objects to nothing at the bottom of your script is
> a waste of time anyway. The script engine will release them for you.
> Anything you have heard to the contrary is simply FUD.
>
In most cases, yes, but there are cases (notably ADO) where resources need
to be closed and released in the correct order.

--
Microsoft MVP - ASP/ASP.NET
Please reply to the newsgroup. This email account is my spam trap so I
don't check it very often. If you must reply off-line, then remove the
"NO SPAM"



Re: The necessity of Setting Objects to Nothing by mr_unreliable

mr_unreliable
Fri May 12 16:44:34 CDT 2006

Sorry, but I just couldn't resist adding some "fud".

For one, I do agree with Mr Jones that if you trust microsoft
to clean up for you then that is sufficient -- most of the time.

I also agree with Mr Barrows, there are situations where
you _must_ clean up for yourself. One case I (vividly)
recall: one object uses another object's methods in its
cleanup routine. Microsoft arbitrarily closed the second
object first, and so the script crashed when microsoft
attempted to close the first object. The remedy was to
EXPLICITLY set the first object to nothing, and then
the second.

This question comes up frequently -- and I suspect the reason
is that as you read through the scripting documentation, you
will see "set x = nothing" used repeatedly, even consistently.
Now, if setting x to nothing is so bad, then why do microsoft's
own documentation specialists repeatedly do it in the scripting
documntation? Are they purposely leading us astray? Are they
ignorant? Have they not consulted with Mr Jones? Even, are
they deliberately contributing to "FUD"?

I think I know why. If you happen to look at a lot of
visual basic (classic) code, you will see coders -- and I
must say coders which substantial skill -- using the
"set x = nothing" all the time. I think the reason is that
they are attempting to release objects AS SOON AS THEY ARE
NO LONGER NEEDED. After all, why hang onto objects that
you are not going to be using again which will only take up
memory that may otherwise be put to better use? I suspect
it is that "hang-over" thought process from the vb-world
that has influenced those microsoft documentation specialists
who wrote the scripting documentation to include so many
"set x = nothing" statements in their coding examples.

As for myself, I ALWAYS set the actX objects to nothing,
either when they are no longer needed, or before I close
my scripts. And it doesn't bother me at all that Mr Jones
is holding his nose in disgust, or even projectile vomiting
into his toilet when he sees my code. Call me mister fud.

cheers, jw

Anthony Jones wrote:
> "Highlander" <tron9901@msn.com> wrote in message
> news:1147446470.966295.258350@u72g2000cwu.googlegroups.com...
>> Hello all. When creating scripts, I've made it a practice to set
>> objects to nothing as the script closes in order to free memory
>> resources. But what happens when you've got a script that is running as
>> a Windows Service (SRVANY.EXE)?
>>
>> In my script I've got a "Do While" Loop that repeats every 15 minutes
>> (Wscript.Sleep 900000) . So the script will keep running indefinitely
>> until I stop the Windows Service. But when I do stop the service, the
>> commands that set objects to nothing won't execute - since they are
>> outside of the "Do While" Loop. What to do?
>>
>
> A few things.
>
> If it's a service and the service it stopped then the process running the
> service is shutdown. It's doesn't matter how badly you code there no memory
> allocation survives the destruction of the process.
>
> If you have objects holding on to significant resources or holding things
> open that don't need to be open during the 15 Minute interval between runs
> then you should release them from inside your outer loop.
>
> Setting all these objects to nothing at the bottom of your script is a waste
> of time anyway. The script engine will release them for you. Anything you
> have heard to the contrary is simply FUD.
>
> Anthony.
>
>
>

Re: The necessity of Setting Objects to Nothing by mayayana

mayayana
Fri May 12 21:51:56 CDT 2006

> As for myself, I ALWAYS set the actX objects to nothing,
> either when they are no longer needed, or before I close
> my scripts. And it doesn't bother me at all that Mr Jones
> is holding his nose in disgust, or even projectile vomiting
> into his toilet when he sees my code. Call me mister fud.
>
I'll second that. I find it odd that so many people
have such strong reactions against simply being thorough.
My own theory is that Microsoft is moving toward total
memory management and the party line, therefore, is
that people people should think in those terms, not being
concerned with cleanup.
Then again, this is the company that's getting ready to
release an OS that needs about 1 GB of RAM just to sit
there. So maybe it's not so well advised to follow their
lead.....Personally, if I wanted an object every 15 minutes I'd
unload it each time.



Re: The necessity of Setting Objects to Nothing by Bob

Bob
Sat May 13 05:19:33 CDT 2006

mayayana wrote:
>> As for myself, I ALWAYS set the actX objects to nothing,
>> either when they are no longer needed, or before I close
>> my scripts. And it doesn't bother me at all that Mr Jones
>> is holding his nose in disgust, or even projectile vomiting
>> into his toilet when he sees my code. Call me mister fud.
>>
> I'll second that. I find it odd that so many people
> have such strong reactions against simply being thorough.
> My own theory is that Microsoft is moving toward total
> memory management and the party line, therefore, is
> that people people should think in those terms, not being
> concerned with cleanup.
> Then again, this is the company that's getting ready to
> release an OS that needs about 1 GB of RAM just to sit
> there. So maybe it's not so well advised to follow their
> lead.....Personally, if I wanted an object every 15 minutes I'd
> unload it each time.

Just to add fuel to the fire:
http://blogs.msdn.com/ericlippert/archive/2004/04/28/122259.aspx

--
Microsoft MVP - ASP/ASP.NET
Please reply to the newsgroup. This email account is my spam trap so I
don't check it very often. If you must reply off-line, then remove the
"NO SPAM"



Re: The necessity of Setting Objects to Nothing by Anthony

Anthony
Sat May 13 07:18:40 CDT 2006


>
> As for myself, I ALWAYS set the actX objects to nothing,
> either when they are no longer needed, or before I close
> my scripts. And it doesn't bother me at all that Mr Jones
> is holding his nose in disgust, or even projectile vomiting
> into his toilet when he sees my code. Call me mister fud.
>

Good I like some one who is prepared to stick to his guns and can argue
their corner.

I would consider lines of code that don't do anything a bad smell but I
probably wouldn't go so far as to vomit.




Re: The necessity of Setting Objects to Nothing by mayayana

mayayana
Sat May 13 11:54:42 CDT 2006


> >> As for myself, I ALWAYS set the actX objects to nothing,
> >> either when they are no longer needed, or before I close
> >> my scripts. And it doesn't bother me at all that Mr Jones
> >> is holding his nose in disgust, or even projectile vomiting
> >> into his toilet when he sees my code. Call me mister fud.
> >>
> > I'll second that. I find it odd that so many people
> > have such strong reactions against simply being thorough.
> > My own theory is that Microsoft is moving toward total
> > memory management and the party line, therefore, is
> > that people people should think in those terms, not being
> > concerned with cleanup.
> > Then again, this is the company that's getting ready to
> > release an OS that needs about 1 GB of RAM just to sit
> > there. So maybe it's not so well advised to follow their
> > lead.....Personally, if I wanted an object every 15 minutes I'd
> > unload it each time.
>
> Just to add fuel to the fire:
> http://blogs.msdn.com/ericlippert/archive/2004/04/28/122259.aspx
>
Yes, Eric Lippert is good at "inflammatory"
contributions. :)