AutoHotkey Community

It is currently May 26th, 2012, 10:54 pm

All times are UTC [ DST ]




Post new topic Reply to topic  [ 7 posts ] 
Author Message
PostPosted: September 9th, 2009, 2:24 am 
Offline

Joined: March 27th, 2009, 12:46 pm
Posts: 76
Location: Dublin, IE
I was looking at the following post to try and find a process' RAM memory usage and found that I had to get the process' memory address. I searched all over the forum and could not find out how to get the address through AHK.

Any help would be appreciated.

From http://www.autohotkey.com/forum/viewtopic.php?p=204378

Code:
; Get the index of the currently playing track from winamp.

AutoTrim, Off

WinGet, windowGH, ID, ahk_class AspyrGH3
if windowGH =
{
   MsgBox GH3 does not appear to be running.
   Exit
}

; Store the address in a new var.
address = 0xA90BE0

; Get the Process ID of GH3.  It will be stored in the output-parameter PID.
DllCall("GetWindowThreadProcessId", "int", windowGH, "UInt *", PID, "UInt")
if (ErrorLevel or !PID)
{
   MsgBox GetWindowThreadProcessId failed.
   Exit
}

; Open the process so we can to stuff with it.
; The call will return a process handle.
ProcessHandle := DllCall("OpenProcess", "int", 24, "char", 0, "UInt", PID, "UInt")
if (ErrorLevel or !ProcessHandle)
{
   MsgBox OpenProcess failed.
   Exit
}

   ; must contain exactly one character because ReadProcessMemory won't terminate
   ; the string, only overwrite its contents.
   Output := "x"  ; Put exactly one character in as a placeholder.
   tempVar := DllCall("ReadProcessMemory", "UInt", ProcessHandle, "UInt", address, "str", Output, "Uint", 4, "Uint *", 0)
   ; Error checking - i.e. no permission for reading from the process's memory
   if (ErrorLevel or !tempVar)
   {
      DllCall("CloseHandle", "int", ProcessHandle)
      MsgBox ReadProcessMemory failed.
      Exit

}

DllCall("CloseHandle", "int", ProcessHandle)  ; ErrorLevel and return value are not checked.

msgbox %output%

_________________
My Scripts


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 9th, 2009, 7:15 am 
Offline

Joined: February 24th, 2005, 8:45 am
Posts: 278
You should be using GetProcessMemoryInfo [msdn] to get the memory usage of a process.

_________________
My small "thanks" to AHK in shape of these dedicated 3d images
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 9th, 2009, 4:42 pm 
Offline
User avatar

Joined: March 19th, 2008, 12:43 am
Posts: 5480
Location: the tunnel(?=light)
GetProcessMemoryInfo function

_________________
Image
Try Quick Search for Autohotkey or see the tutorial for newbies.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 9th, 2009, 11:23 pm 
Offline

Joined: March 27th, 2009, 12:46 pm
Posts: 76
Location: Dublin, IE
sinkfaze wrote:

Thanks! It seems to work, but I keep getting a different value from AHK than what the Windows 7 Task Manager states. I'm assuming it's because the W7TM's column title says "Memory (Private Working Set)"?

A few examples of what I mean:

Quote:
dropbox.exe
AHK: 20088 K
WTM: 13584 K

subsonic-agent.exe
AHK: 26988 K
WTM: 15788 K

rocketdock.exe
AHK: 12384 K
WTM: 5420 K

_________________
My Scripts


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 30th, 2009, 11:48 am 
Offline

Joined: October 14th, 2009, 12:30 am
Posts: 20
Voltron43 wrote:
sinkfaze wrote:

Thanks! It seems to work, but I keep getting a different value from AHK than what the Windows 7 Task Manager states. I'm assuming it's because the W7TM's column title says "Memory (Private Working Set)"?

A few examples of what I mean:

Quote:
dropbox.exe
AHK: 20088 K
WTM: 13584 K

subsonic-agent.exe
AHK: 26988 K
WTM: 15788 K

rocketdock.exe
AHK: 12384 K
WTM: 5420 K


Memory Management is, contrary to popular belief, a gigantic hassle.

There are several different ways of displaying/reporting memory usage. And the fact is that none of them are "correct". The way Task Manager uses is Working Set. The way I would prefer is Physical Memory Usage, but that number is pretty much impossible to retrieve, save for the total Physical Memory Usage. So, if you want it like Task Manager, Working Set is the way to go. I don't know how to specify that in AHK, but I felt that I should at least contribute with what little I know :D


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 30th, 2009, 2:54 pm 
Offline

Joined: March 27th, 2009, 12:46 pm
Posts: 76
Location: Dublin, IE
skribb wrote:
...but I felt that I should at least contribute with what little I know :D


Thanks for contributing.

_________________
My Scripts


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 12th, 2010, 9:27 pm 
Offline

Joined: September 28th, 2004, 7:10 am
Posts: 17
This is an excellent starting place, but as the last author noted, the "Working Set" is virtually worthless as an indicator of memory consumption. I could give you a long boring explanation, but the sort answer is that you want "Virtual Size" or "Private Bytes" (same thing, different versions of Windows).

I extended the example to use PROCESS_MEMORY_COUNTERS_EX, which adds Private Bytes. Use GetProcessMemory_All for this.

I also made a simpler version that returns JUST the Private Bytes, in B, K or M. It's the one I use most. Call GetProcessMemory_Private with the process name, and an optional parameter indicating the unit of measure (default KB).

To use this, just save it as C:\Program Files\AutoHotkey\Lib\GetProcessMemory.ahk, and call the functions.
Code:
;=============================================================================================================
; Func: GetProcessMemory_Private
; Get the number of private bytes used by a specified process.  Result is in K by default, but can also be in
; bytes or MB.
;
; Params:
;   ProcName    - Name of Process (e.g. Firefox.exe)
;   Units       - Optional Unit of Measure B | K | M.  Defaults to K (Kilobytes)
;
; Returns:
;   Private bytes used by the process
;-------------------------------------------------------------------------------------------------------------
GetProcessMemory_Private(ProcName, Units="K") {
    Process, Exist, %ProcName%
    pid := Errorlevel

    ; get process handle
    hProcess := DllCall( "OpenProcess", UInt, 0x10|0x400, Int, false, UInt, pid )

    ; get memory info
    PROCESS_MEMORY_COUNTERS_EX := VarSetCapacity(memCounters, 44, 0)
    DllCall( "psapi.dll\GetProcessMemoryInfo", UInt, hProcess, UInt, &memCounters, UInt, PROCESS_MEMORY_COUNTERS_EX )
    DllCall( "CloseHandle", UInt, hProcess )

    SetFormat, Float, 0.0 ; round up K

    PrivateBytes := NumGet(memCounters, 40, "UInt")
    if (Units == "B")
        return PrivateBytes
    if (Units == "K")
        Return PrivateBytes / 1024
    if (Units == "M")
        Return PrivateBytes / 1024 / 1024
}


;=============================================================================================================
; Func: GetProcessMemory_All
; Get all Process Memory Usage Counters.  Mimics what's shown in Task Manager.
;
; Params:
;   ProcName    - Name of Process (e.g. Firefox.exe)
;
; Returns:
;   String with all values in KB as one big string.  Use a Regular Expression to parse out the value you want.
;-------------------------------------------------------------------------------------------------------------
GetProcessMemory_All(ProcName) {
    Process, Exist, %ProcName%
    pid := Errorlevel

    ; get process handle
    hProcess := DllCall( "OpenProcess", UInt, 0x10|0x400, Int, false, UInt, pid )

    ; get memory info
    PROCESS_MEMORY_COUNTERS_EX := VarSetCapacity(memCounters, 44, 0)
    DllCall( "psapi.dll\GetProcessMemoryInfo", UInt, hProcess, UInt, &memCounters, UInt, PROCESS_MEMORY_COUNTERS_EX )
    DllCall( "CloseHandle", UInt, hProcess )

    list := "cb,PageFaultCount,PeakWorkingSetSize,WorkingSetSize,QuotaPeakPagedPoolUsage"
          . ",QuotaPagedPoolUsage,QuotaPeakNonPagedPoolUsage,QuotaNonPagedPoolUsage"
          . ",PagefileUsage,PeakPagefileUsage,PrivateUsage"

    n := 0
    Loop, Parse, list, `,
    {
        n += 4
        SetFormat, Float, 0.0 ; round up K
        this := A_Loopfield
        this := NumGet( memCounters, (A_Index = 1 ? 0 : n-4), "UInt") / 1024

        ; omit cb
        If A_Index != 1
            info .= A_Loopfield . ": " . this . " K" . ( A_Loopfield != "" ? "`n" : "" )
    }

    Return "[" . pid . "] " . pname . "`n`n" . info ; for everything
}



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

All times are UTC [ DST ]


Who is online

Users browsing this forum: Bing [Bot], Google [Bot], hyper_, JSLover, Kirtman, Leef_me, Maestr0, Miguel, XstatyK, Yahoo [Bot] and 61 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