 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
*MsgBox Guest
|
Posted: Thu Apr 19, 2007 10:39 pm Post subject: How to detect "Top Process" |
|
|
Is it possible to detect the "top process" using AutoHotkey?
By "top process" I mean, the running process that is using the most CPU time at any moment.
The only things that I have found that (sort of) work are a vbscript that outputs to a txt file and the Task Managers "CPU" column. Neither are what I am looking for as the vbscript takes too long to complete and TM has to be running continually.
I am writing a script to replace "CoolMon" a system monitoring app and top process is the one thing I can't give up, its too useful!!.
Below is the vbscript. I have edited it from the original version so that it just outputs the process name. To be honest though, I haven't got a clue what I'm looking at...I don't know vb al all.
I am hoping that maybe there is something in the script that AutoHotkey can use, possibly DllCall?? (something else that I haven't a clue about!)
Any help and guidance with this will be very much appreciated.
Thanks.
| Code: | '***** To make it easy, keep both sleep.vbs and THIS script in the same folder.
DIM First(1000,3) 'keeps track of the 1st snapshot info
DIM Second(1000,3) 'keeps track of the 2nd snapshot info
Directory = ""
Sleep = "sleep.vbs"
oPath = " "
oFile = "Processes.txt"
TheDate = Date
TheTime = Time
Set fs = CreateObject("Scripting.FileSystemObject")
Set colItems = GetObject("winmgmts:{impersonationLevel=impersonate}").InstancesOf ("Win32_Process")
Set outFile = fs.CreateTextFile(oPath & oFile, True)
For Each objProcess in GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2").ExecQuery("SELECT * FROM Win32_Process")
x=x+1
First(x,0) = timer 'current time
First(x,1) = objProcess.Name 'process name
First(x,2) = (CSng(objProcess.KernelModeTime) + CSng(objProcess.UserModeTime)) / 10000000 'how many seconds the process has used since it first started
Next
'CreateObject("WScript.Shell").Run Directory & Sleep,1,True
For Each objProcess in GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2").ExecQuery("SELECT * FROM Win32_Process")
y=y+1
Second(y,0) = timer
Second(y,1) = objProcess.Name
Second(y,2) = (CSng(objProcess.KernelModeTime) + CSng(objProcess.UserModeTime)) / 10000000
Next
For z = 1 to y
ProcessTime = round(((Second(z,2)-First(z,2)) / (Second(z,0)-First(z,0))) * 100) 'calculates to see if there's been an increase in process activity
If ProcessTime then
TotalProcessTime = TotalProcessTime + ProcessTime
'-----The following processes are excluded from being the top process. You can add/remove whatever you want.
If Second(z,1) <> "System Idle Process" then
If ProcessTime > TopProcessTime then
TopProcessTime = ProcessTime
reduce = InStr(Second(z,1), ".") - 1
If reduce > 0 then
TopProcessName = Left(Second(z,1),reduce) 'removes the extension (.xxx)
Else
TopProcessName = Second(z,1)
End If
End If
End If
End If
Next
If TopProcessTime > 100 then TopProcessTime = 100
FindTheTopProcess = TopProcessName & " - " & TopProcessTime & "%" : If FindTheTopProcess = " - %" then FindTheTopProcess = ""
If TopProcessName = "" then FindTheTopProcess = " "
TopProcess = FindTheTopProcess
if TopProcessTime < 50 then FindTheTopProcess = ""
Outfile.Write "" & TopProcessName & ""
outfile.close |
|
|
| Back to top |
|
 |
BoBo Guest
|
Posted: Fri Apr 20, 2007 8:03 am Post subject: |
|
|
| Quote: | | I am hoping that maybe there is something in the script that AutoHotkey can use, possibly DllCall?? | Good chance. If not, I think you should check out Sysinternals PSList tool meanwhile. |
|
| Back to top |
|
 |
Sean
Joined: 12 Feb 2007 Posts: 2462
|
|
| Back to top |
|
 |
*MsgBox Guest
|
Posted: Sun Apr 22, 2007 1:07 am Post subject: |
|
|
Thanks both of you.
I will have a go at making something out of what you have given me.... |
|
| Back to top |
|
 |
MsgBox
Joined: 17 Nov 2005 Posts: 181 Location: Leicester, UK
|
Posted: Sun Apr 22, 2007 6:50 pm Post subject: |
|
|
Well I'm not having too much luck here.
I can get the top process with Seans script but...the script itself is using a lot of cpu time and as it is supposed to be working "quietly" in the background it sort of defeats the object etc....sigh!
| Code: | #NoEnv
#Persistent
#Include CoHelper.ahk
Namespace := "root\cimv2"
Class := "Win32_Process"
QLang := "WQL"
Query := "SELECT Caption, KernelModeTime, UserModeTime FROM " . Class
Ansi2Unicode(Namespace, wNamespace)
Ansi2Unicode(QLang, wQLang)
Ansi2Unicode(Query, wQuery)
CoInitialize()
GUID4String(CLSID_SWbemLocator, "{76A64158-CB41-11D1-8B02-00600806D9B6}")
GUID4String( IID_ISWbemLocator, "{76A6415B-CB41-11D1-8B02-00600806D9B6}")
ploc := CreateObject(CLSID_SWbemLocator, IID_ISWbemLocator)
DllCall(VTable(ploc, 7), "Uint", ploc, "Uint", 0, "str", wNamespace
, "Uint", 0, "Uint", 0, "Uint", 0, "Uint", 0, "int", 0, "Uint", 0, "UintP", psvc)
SetTimer TP, 50
TP:
SetTimer TP, Off
GoSub GetData ; Get first snapshot.
Sleep 10
GoSub GetData ; Get second snapshot.
Snap = %sn1%
lp = 1
GoSub Process ; Build first ss list.
Snap = %sn2%
lp = 2
GoSub Process ; Compare lists
Sort c, NR ; Bring highest cpu user to top.
ToolTip % c "Processes: " cnt
;MsgBox % c "Processes: " cnt
lp=
sn1=
sn2=
snap1=
ttl=
c=
SetTimer TP, On
Return
DllCall(VTable(penm, 2), "Unit", penm)
DllCall(VTable(pset, 2), "Unit", pset)
DllCall(VTable(psvc, 2), "Unit", psvc)
DllCall(VTable(ploc, 2), "Unit", ploc)
CoUninitialize()
Process:
StringReplace Snap, Snap, `ninstance of Win32_Process`n{,|,A
StringReplace Snap, Snap, %A_Tab%,, A
StringReplace Snap, Snap, },,A
StringReplace Snap, Snap, `;,, A
Loop Parse, Snap, |, "
{
line := A_LoopField
IfEqual line,, Continue
Loop Parse, line, `n, "
{
l := A_LoopField
IfInString l, Caption
{
StringGetPos pos, l, "
StringTrimLeft n, l, % pos+1
Continue
}
IfInString l, Handle
{
StringGetPos pos, l, "
StringTrimLeft h, l, % pos+1
Continue
}
IfInString l, KernelModeTime
{
StringGetPos pos, l, "
StringTrimLeft k, l, % pos+1
Continue
}
IfInString l, UserModeTime
{
StringGetPos pos, l, "
StringTrimLeft u, l, % pos+1
Continue
}
}
If lp = 1 ; First snapshot.
{
s1 := (k + u)/10000000 ; Add KernelModeTime and UserModeTime together.
Snap1 = %Snap1%%n%%h%-%s1%`n ; Build fist snapshot list.
Continue
}
Else { ; Second snapshot.
Sleep 10
s2 := (k + u)/10000000
Loop Parse, Snap1, `n
{
l := A_LoopField
IfInString l, System Idle Process
Continue
IfInString l, %n%%h% ; Find matching process
{
StringGetPos pos, l, -
StringTrimLeft s1, l, % pos+1 ; Get total time from 1st snap.
If s2 = %s1% ; No change.
Continue
ttl := (s2 - s1) ;/10000000 ; Process was active...
c = %c%%ttl%-%n%`n ; Build a list.
Continue
}
}
}
}
Return
GetData:
lp++ ; Which loop identifier.
DllCall(VTable(psvc,15), "Uint", psvc, "str", wQuery, "str", wQLang, "Uint", 0x30, "Uint", 0, "UintP", pset)
DllCall(VTable(pset, 7), "Uint", pset, "UintP", penm)
VarSetCapacity(varg, 8 * 2)
Loop
{
cnt := A_Index ; Count number of processes.
If DllCall(VTable(penm, 3), "Uint", penm, "Uint", 1, "Uint", &varg, "Uint", 0)
Break
pobj := DecodeInteger(&varg + 8)
DllCall(VTable(pobj,22), "Uint", pobj, "Uint", 0, "UintP", pString)
DllCall(VTable(pobj, 2), "Unit", pobj)
Unicode2Ansi(pString, sString)
SysFreeString(pString)
If lp = 1
{
sn1 = %sn1%%sString%`n
}
Else {
sn2 = %sn2%%sString%`n
}
}
Return
;Query := "SELECT Caption, KernelModeTime, UserModeTime FROM " . Class
|
| BoBo wrote: | | Good chance. If not, I think you should check out Sysinternals PSList tool meanwhile. |
psList is a great little tool and the -s switch makes it run in task manager mode showing the top process.
My idea was to redirect the onscreen output to a file then have my script read then delete that file every second. The problem is that the file is locked and cannot be deleted....arrgh!
Is there an easy way to forcibly delete a locked file?
This too used more cpu time but not quite as much as the other script.
Here's a few links on this subject:
http://www.alexfedotov.com/samples/wmitop.asp
http://www.microsoft.com/technet/scriptcenter/resources/qanda/sept05/hey0922.mspx
http://www.codeproject.com/threads/Get_CPU_Usage.asp
I have downloaded a dll that CoolMon uses to get the Top Process, is there any way that that could be used...or is that a stupid question?
Anyway I'm stuck now, any idea's?
Thanks. |
|
| Back to top |
|
 |
MsgBox
Joined: 17 Nov 2005 Posts: 181 Location: Leicester, UK
|
Posted: Tue Apr 24, 2007 8:16 pm Post subject: |
|
|
Here is the best (resource wise) that I have come up with.
Although not ideal, it does the job.
These two examples use Task Manager to get the info.
The first with the default columns and the second with just the "Image Name" and "CPU" columns which doesn't hog the cpu time.
| Code: | #Persistent
DetectHiddenWindows On
Run taskmgr.exe,,, PID
WinWait ahk_pid %PID%
Control TabLeft,9, SysTabControl321, ahk_pid %PID%
Control TabRight,1,SysTabControl321, ahk_pid %PID%
ControlClick x270 y100, ahk_pid %PID%,,, 2
WinHide ahk_pid %PID%
SetTimer TopProcess, 50
OnExit Out
Return
TopProcess:
SetTimer TopProcess, Off
ControlGet list, List, ,SysListView321, ahk_pid %PID%
Loop Parse, list, `n
{
l := A_LoopField
IfInString l, System Idle Process, Continue
Loop Parse, l, %A_Tab%
{
l1 := A_LoopField
s = %s%%l1%|
IfEqual A_Index, 3, Break
}
Break
}
StringSplit d, s, |
StringTrimRight d1, d1, 4
If d3 < 01
tp=
Else
tp = %d1% @ %d3%`% CPU
ToolTip % tp
s=
SetTimer TopProcess, On
Return
Out:
WinClose ahk_pid %PID%
ExitApp
Return |
| Code: | ; Unselect "Memory Usage" and "User Name" in Task Manager. (Uses less system resources)
#Persistent
DetectHiddenWindows On
Run taskmgr.exe,,, PID
WinWait ahk_pid %PID%
Control TabLeft,9, SysTabControl321, ahk_pid %PID%
Control TabRight,1,SysTabControl321, ahk_pid %PID%
ControlClick x170 y100, ahk_pid %PID%,,, 2
WinHide ahk_pid %PID%
SetTimer TopProcess, 50
OnExit Out
Return
TopProcess:
SetTimer TopProcess, Off
ControlGet list, List, ,SysListView321, ahk_pid %PID%
Loop Parse, list, `n
{
l := A_LoopField
IfInString l, System Idle Process, Continue
Loop Parse, l, %A_Tab%
{
l1 := A_LoopField
s = %s%%l1%|
IfEqual A_Index, 2, Break
}
Break
}
StringSplit d, s, |
StringTrimRight d1, d1, 4
If d2 < 01
tp=
Else
tp = %d1% @ %d2%`% CPU
ToolTip % tp
s=
SetTimer TopProcess, On
Return
Out:
WinClose ahk_pid %PID%
ExitApp
Return |
|
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|