AutoHotkey Community

It is currently May 25th, 2012, 2:33 am

All times are UTC [ DST ]




Post new topic Reply to topic  [ 6 posts ] 
Author Message
PostPosted: April 19th, 2007, 11:39 pm 
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


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: April 20th, 2007, 9:03 am 
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.


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: April 20th, 2007, 9:24 am 
Offline

Joined: February 12th, 2007, 7:54 am
Posts: 2462
You may use this script after adjusting it to your need:
http://www.autohotkey.com/forum/viewtopic.php?t=16632

replacing Query with
Code:
Query := "SELECT Caption, KernelModeTime, UserModeTime FROM " . Class


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 22nd, 2007, 2:07 am 
Thanks both of you. 8)

I will have a go at making something out of what you have given me....


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: April 22nd, 2007, 7:50 pm 
Offline

Joined: November 17th, 2005, 10:14 pm
Posts: 196
Location: Leicester, UK
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.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 24th, 2007, 9:16 pm 
Offline

Joined: November 17th, 2005, 10:14 pm
Posts: 196
Location: Leicester, UK
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


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 6 posts ] 

All times are UTC [ DST ]


Who is online

Users browsing this forum: Bing [Bot], lblb and 15 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group