Eseguendo via WSH pesanti interrogazioni su Database o File System ho notato che entrambi i motori (cscript/wscript) tendono a consumare moltissima CPU (fino al 100%!) rubando preziose risorse anche ad alcuni processi prioritari e causando quindi pesanti rallenamenti nell'esecuzione del sistema e dei servizi.
Per ovviare a questo problema in passato ho cercato di "rallentare" in maniera artificiale l'esecuzione degli script inserendo alcuni "sleep" all'interno del codice sorgente.
Se pur questa non fosse una soluzione molto elegante si è rivelata piuttosto efficace ed estremamente facile da implementare, l'unica pecca era rappresentata dal fatto di dover spesso accettare tempi di esecuzione "allungati" dalle pause forzate delle istruzioni "sleep".
Di recente, durante la realizzazione di un nuovo progetto, ho sentito il bisogno di trovare un metodo migliore del precedente per rendere gli script meno aggressivi sulle risorse del sistema, ecco come ho fatto:
Dim objWMI, objProc, ColProcs
If LCase(Right(WScript.FullName, 11)) = "cscript.exe" Then
Set objWMI = GetObject("winmgmts:\\.\root\cimv2")
Set ColProcs = objWMI.ExecQuery("SELECT * FROM Win32_Process WHERE Name='cscript.exe'")
For Each objProc in ColProcs
If (InStr(LCase(objProc.CommandLine), LCase(WScript.ScriptName)) > 0) Then
objProc.SetPriority 64
End If
Next
Set objWMI = Nothing
Else
Set objWMI = GetObject("winmgmts:\\.\root\cimv2")
Set ColProcs = objWMI.ExecQuery("SELECT * FROM Win32_Process WHERE Name='wscript.exe'")
For Each objProc in ColProcs
If (InStr(LCase(objProc.CommandLine), LCase(WScript.ScriptName)) > 0) Then
objProc.SetPriority 64
End If
Next
Set objWMI = Nothing
End If
Inserendo questo codice all'inizio di qualsiasi script si può fare in modo che il processo incaricato di eseguirlo abbia, nel sistema, la minor priorità possibile.
L'unica nota dolente di questo approccio basato su WMI è che non funziona su Windows 2000 poiché la proprietà "CommandLine" della classe "Win32_Process" è stata introdotta da Windows XP.
Per evitare il verificarsi di errori su Windows 2000 vi consiglio di arricchirlo con una funzione in grado di discriminare la versione del sistema operativo, ad esempio:
Dim objWMI, objProc, ColProcs
If Not IsWin2000 Then
If LCase(Right(WScript.FullName, 11)) = "cscript.exe" Then
Set objWMI = GetObject("winmgmts:\\.\root\cimv2")
Set ColProcs = objWMI.ExecQuery("SELECT * FROM Win32_Process WHERE Name='cscript.exe'")
For Each objProc in ColProcs
If (InStr(LCase(objProc.CommandLine), LCase(WScript.ScriptName)) > 0) Then
objProc.SetPriority 64
End If
Next
Set objWMI = Nothing
Else
Set objWMI = GetObject("winmgmts:\\.\root\cimv2")
Set ColProcs = objWMI.ExecQuery("SELECT * FROM Win32_Process WHERE Name='wscript.exe'")
For Each objProc in ColProcs
If (InStr(LCase(objProc.CommandLine), LCase(WScript.ScriptName)) > 0) Then
objProc.SetPriority 64
End If
Next
Set objWMI = Nothing
End If
End If
Function IsWin2000
Dim TmpObjWMI, TmpObjOS, TmpColOSs
IsWin2000 = False
Set TmpObjWMI = GetObject("winmgmts:\\.\root\cimv2")
Set TmpColOSs = TmpObjWMI.ExecQuery ("Select * from Win32_OperatingSystem")
For Each TmpObjOS in TmpColOSs
If (Instr(LCase(TmpObjOS.Caption), Lcase("2000")) > 0) Then
IsWin2000 = True
End If
Next
Set TmpObjWMI = Nothing
End Function
Autore
Mirko Iodice
mirko -at- notageek (.dot) it