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 SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Monitor % Process CPU Usage (specific process) 1

Status
Not open for further replies.

digimahn

IS-IT--Management
Jul 25, 2002
27
0
0
US
I have asked before...

I think the subject is a little more "descriptive" this time and I hope I can get the help :) It's been quite a few months of on/off research and testing and now another month pretty much dedicated to frustration has passed by.

Object of script:
[ol][li]Pause Default Printer [/li]
[li]Start and run an "invoicing" application [/li]
[li]When app goes Idle - terminate app [/li]
[li]Scan \WINNT\system32\spool\PRINTERS\*.SPL files for specific "data" and delete those .SPL files - allocate a sleep value of .65 - .9 seconds per .SPL for search to complete (with progress display) [/li]
[li]Stop and Start Print Spooler service [/li]
[li]Refresh default printer queue display [/li]
[li]Un-pause default printer (if service is not restarted and queue not refreshed then event log will contain 1 error message for each item missing .SPL - assumes default print server event log options enabled) [/ol][/li]
Now where I get stuck and have been stuck it to be able to tell when this crappy VB application has gone idle (3) and the only way I see doing that is via WMI.

Using WMI I can get at the "Win32_PerfRawData_PerfOS_Processor" raw data performance counter class - specifically "PercentProcessorTime" ... but my question is: is this where the column in taskmanager labled "CPU" is derived from? This is the only value that seems to make sense after reading the WMI SDK for the past week.

I can't seem to figure out how get this info per process...
I used line items so you can easily see each line of code/script

[ol][li]strComputer = "."[/li]
[li]Set objWMIService = GetObject("winmgmts:" & _
"{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")[/li]
[li]Set colProcesses = objWMIService.ExecQuery ("Select * from Win32_process")[/li]
[li]For Each objProcess in colProcesses[/li]
[li] sngProcessTime = ( CSng(objProcess.KernelModeTime) + CSng(objProcess.UserModeTime)) / 10000000[/li]
[li] Wscript.echo objProcess.name & ": " & Round(sngProcessTime,2) & " Seconds"[/li]
[li]Next[/ol][/li]
I figured out how to get at the time column and convert it to seconds - WHOOPIE! I don't need that...

Then I found this while reading about WMI on MSDN:
[ol][li]Set objService = GetObject("Winmgmts:{impersonationlevel=impersonate}!\Root\Cimv2")[/li]
[li]For i = 1 to 8[/li]
[li]Set objInstance1 = objService.Get("Win32_PerfRawData_PerfOS_Processor.Name='_Total'")[/li]
[li]N1 = objInstance1.PercentProcessorTime[/li]
[li]D1 = objInstance1.TimeStamp_Sys100NS[/li]
[li]WScript.Sleep(2000)[/li]
[li]Set perf_instance2 = objService.get("Win32_PerfRawData_PerfOS_Processor.Name='_Total'")[/li]
[li]N2 = perf_instance2.PercentProcessorTime[/li]
[li]D2 = perf_instance2.TimeStamp_Sys100NS[/li]
[li]PercentProcessorTime = (1 - ((N2 - N1)/(D2-D1)))*100[/li]
[li]WScript.Echo "% Processor Time=" , Round(PercentProcessorTime,2)[/li]
[li]Next[/ol][/li]
This one gets at the data, BUT it's for the TOTAL processor time, I understand the 2 second difference sample and the formula, but no matter what I try in several combinations this is as close as I get.

How can I "echo" this PercentProcessorTime for a specific process? I'm going to go freeeeegin crazy :)

Can anyone help me?
DigiMahn

P.s.
I know I could use the TGML "CODE" tags but the wrapping was just too crazy looking for my anal retentive self :) but here is what I have so far without #3:
Code:
set WshShell = CreateObject("WScript.Shell")
Set IE = CreateObject("InternetExplorer.Application")
Set shl = CreateObject("Shell.Application")
Set fso = CreateObject("Scripting.FileSystemObject")

Set oShell = CreateObject("Shell.Application")

Set oFolder = oShell.Namespace("C:\WINNT\system32\spool\PRINTERS\")

nCounter = 0

For Each oFile in oFolder.Items

If lcase(Right(oFile.Name,4))=".spl" Then ncounter = nCounter + 1

Next


strMyDocPath = WshShell.SpecialFolders("MyDocuments")
strTempFile = strMyDocPath & "\RenPStat.html"
SetupIE(strTempFile)
Set objDIV = IE.Document.All("MakeMeAnObject")
objDIV.InnerHTML = &quot;Processing Search Script...<BR><FONT SIZE=1>Next process: Locate and Delete --- ---'s invoices&quot;
WScript.Sleep 2000

shl.FindFiles	
WScript.Sleep 1000
WshShell.SendKeys &quot;%M&quot;
WshShell.SendKeys &quot;*.SPL&quot;
WshShell.SendKeys &quot;%L&quot;
WshShell.SendKeys &quot;C:\WINNT\system32\spool\PRINTERS&quot;

WshShell.SendKeys &quot;%C&quot;
WshShell.SendKeys &quot;AMER150 &quot;
SetupIE(strTempFile)
Set objDIV = IE.Document.All(&quot;MakeMeAnObject&quot;)
objDIV.InnerHTML = &quot;Locating --- --- Invoices...<BR><FONT SIZE=1>Next process: Locate and Delete --- ---'s invoices (in &quot; & (nCounter * .079) & &quot; seconds)&quot;
CommitSearch

WshShell.SendKeys &quot;{TAB 4}&quot;
WshShell.SendKeys &quot;SKIN3910&quot;
CountSPLs
SetupIE(strTempFile)
Set objDIV = IE.Document.All(&quot;MakeMeAnObject&quot;)
objDIV.InnerHTML = &quot;Locating --- --- Invoices...<BR><FONT SIZE=1>Next process: Locate and Delete --- ---'s invoices (in &quot; & (nCounter * .079) & &quot; seconds)&quot;
CommitSearch



Wscript.Sleep 1000
WshShell.SendKeys &quot;%{F4}&quot;
Wscript.Sleep 500
intReturn = WshShell.Run(&quot;C:\TransFlo\rndprint\Stop_svc.bat&quot;, 1, TRUE)
WshShell.AppActivate &quot;HP LaserJet 4000 Series PCL - Paused&quot;
WScript.Sleep 500
WshShell.SendKeys &quot;{F5}&quot;
WScript.Sleep 2000
WshShell.SendKeys &quot;%pa&quot;
SetupIE(strTempFile)
Set objDIV = IE.Document.All(&quot;MakeMeAnObject&quot;)
objDIV.InnerHTML = &quot;Printing Invoices...&quot;
WScript.Quit(1)



Sub SetupIE(File2Load)
IE.Navigate File2Load
IE.ToolBar = False
IE.StatusBar = False
IE.Resizable = False
Do
Loop While IE.Busy
IE.Width = 500
IE.Height = 150
IE.Left = 0
IE.Top = 0
IE.Visible = True
WshShell.AppActivate(&quot;Microsoft Internet Explorer&quot;)
WshShell.AppActivate(&quot;Search Results&quot;)
End Sub

Function CountSPLs()
nCounter = 0

For Each oFile in oFolder.Items

If lcase(Right(oFile.Name,4))=&quot;.spl&quot; Then ncounter = nCounter + 1

Next

End Function

Sub CommitSearch()
WshShell.SendKeys &quot;~&quot;
WScript.Sleep (79 * nCounter)
WshShell.SendKeys &quot;%ea&quot;
WshShell.SendKeys &quot;+{DEL}&quot;
WshShell.SendKeys &quot;Y&quot;
End Sub
 
forgot to mention that I will probably attempt an if then on the processor % usage...

If PercentProcessorTime for &quot;process&quot; > 2 then sleep &quot;x&quot; seconds
If PercentProcessorTime for &quot;process&quot; < 1 then KILL &quot;process&quot;

Thought that may help :)
 
Here's a clue.

The thing I don't like is you've got to use both Win32_Process (for KernalModeTime) and Win32_PerfFormattedData_PerfProc_Process for CPUUsage. But if you are willing to give up some of the details including KernalModeTime (and command line and ...) you can get everything you need from Win32_PerfFormattedData_PerfProc_Process.

for each Process in GetObject(&quot;winmgmts:{impersonationLevel=impersonate}//localhost&quot;).ExecQuery(&quot;Select PercentProcessorTime,IDProcess from Win32_PerfFormattedData_PerfProc_Process where IDProcess=4092&quot;)

WScript.Echo(&quot;================================&quot;)
For Each oProperty In Process.Properties_
WScript.stdout.write vbtab & oProperty.Name & &quot;=&quot;
If IsArray(oProperty) Then
For iCount = 0 To UBound(oProperty)
WScript.stdout.write oProperty.Value(iCount) & &quot;,&quot;
Next
WScript.StdOut.writeline
ElseIf IsNull(oProperty) Then
WScript.stdout.writeline &quot;Property not set&quot;
Else
WScript.stdout.writeline oProperty.Value
End If
Next
WScript.Echo(Process.PercentProcessorTime)
WScript.quit
next

Email me for a script to generate a full set of stats just like our friend taskman...
 
Response Part II:

Seems This Works, I believe..


for each Process in GetObject(&quot;winmgmts:&quot;).ExecQuery(&quot;Select * from Win32_Process&quot;)
WScript.echo Process.name & &quot; &quot; & CPUUSage(Process.Handle) & &quot; %&quot;
Next


Function CPUUSage( ProcID )

On Error Resume Next

Set objService = GetObject(&quot;Winmgmts:{impersonationlevel=impersonate}!\Root\Cimv2&quot;)

For Each objInstance1 in objService.ExecQuery(&quot;Select * from Win32_PerfRawData_PerfProc_Process where IDProcess = '&quot; & ProcID & &quot;'&quot;)
N1 = objInstance1.PercentProcessorTime
D1 = objInstance1.TimeStamp_Sys100NS
Exit For
Next

WScript.Sleep(2000)


For Each perf_instance2 in objService.ExecQuery(&quot;Select * from Win32_PerfRawData_PerfProc_Process where IDProcess = '&quot; & ProcID & &quot;'&quot;)
N2 = perf_instance2.PercentProcessorTime
D2 = perf_instance2.TimeStamp_Sys100NS
Exit For
Next

' CounterType - PERF_100NSEC_TIMER_INV
' Formula - (1- ((N2 - N1) / (D2 - D1))) x 100
Nd = (N2 - N1)
Dd = (D2-D1)
PercentProcessorTime = ( (Nd/Dd)) * 100




CPUUSage = Round(PercentProcessorTime ,0)



End Function
 
PVilevac! Thank you!

I implemented a 3rd party tool that I was able to script to/from - I don't like it this way so THANKS once again!!!!
I like to keep things neat and self contained and avoid scripting with anything that is not native to the OS (if possible).

I kinda gave up on these threads...I was looking for a refresher on WSH and printers and there popped up this thread. I don't write that many scripts, but darn if when I do it's a dOOzy like this one!

...I wonder why email notification did not work...hmm.

I can not see a way to email you - maybe I'm just lost :)

Thank you once more...
 
Just so others have the info:

for each Process in GetObject(&quot;winmgmts:&quot;).ExecQuery(&quot;Select * from Win32_Process where Name = 'rndprint.exe'&quot;)
WScript.echo Process.name & &quot; &quot; & CPUUSage(Process.Handle) & &quot;%&quot;
Next

Function CPUUSage( ProcID )
On Error Resume Next
Set objService = GetObject(&quot;Winmgmts:{impersonationlevel=impersonate}!\Root\Cimv2&quot;)

For Each objInstance1 in objService.ExecQuery(&quot;Select * from Win32_PerfRawData_PerfProc_Process where Name = 'rndprint'&quot;)
N1 = objInstance1.PercentProcessorTime
D1 = objInstance1.TimeStamp_Sys100NS
Exit For
Next

WScript.Sleep(2000)

For Each perf_instance2 in objService.ExecQuery(&quot;Select * from Win32_PerfRawData_PerfProc_Process where Name = 'rndprint'&quot;)
N2 = perf_instance2.PercentProcessorTime
D2 = perf_instance2.TimeStamp_Sys100NS
Exit For
Next

' CounterType - PERF_100NSEC_TIMER_INV
' Formula - (1- ((N2 - N1) / (D2 - D1))) x 100
Nd = (N2 - N1)
Dd = (D2-D1)
PercentProcessorTime = ( (Nd/Dd)) * 100

CPUUSage = Round(PercentProcessorTime ,0)
End Function

The items in bold are the NAME values for my targeted process. Below are two ways to look at all the wonderful items each Class has to offer:

Win32_Process
set wmi = GetObject(&quot;winmgmts:root/CIMV2&quot;)
wql = &quot;select * from Win32_Process&quot;
set result = wmi.ExecQuery(wql)
for each instance in result
response = MsgBox(instance.getObjectText_, vbOKCancel)
if response=vbCancel then exit for
next

Win32_PerfRawData_PerfProc_Process
set wmi = GetObject(&quot;winmgmts:root/CIMV2&quot;)
wql = &quot;select * from Win32_PerfRawData_PerfProc_Process&quot;
set result = wmi.ExecQuery(wql)
for each instance in result
response = MsgBox(instance.getObjectText_, vbOKCancel)
if response=vbCancel then exit for
next


Question:
Since I know EXACTLY what it is I am looking for is it absolutely necessary to enumerate CIMV2 entirely to access this info. This can be time consuming depending on the system involved...is there not a faster way to get at this data?

I sure do hope this helps someone else too!
DigiMahn
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top