L00py Posted December 18, 2007 Share Posted December 18, 2007 Hi all. Quick question for someone more knowledgeable in Win32 API calls. I have the following code: $hProcess = ProcessExists("explorer.exe") $GDIcount = DllCall("user32.dll", "int", "GetGuiResources", "hwnd", $hProcess, "int", 0) _ArrayDisplay($GDIcount, "test") Now, what I expect to happen is that this call returns an INT with the number of GDI Objects in use by the specified process. The array I get returned has the correct PID but the return value in $GDICount[0] is always zero. When I look at the example programs built in other languages, they work as expected in that the return value is the same as the GDI Objects column's value in Task Manager. I have tried using different data types for the $hProcess parameter in the DllCall above, including ptr and int with no change in return values. I tried the same data type changes to the 2nd parameter with no changes either. Does anyone have a suggestion as to why this particular function does not return what I expect? I did try using the MessageBox example from the DllCall help page example and it worked as expected. Thanks for your time! Cheers, L00py Link to comment Share on other sites More sharing options...
Siao Posted December 18, 2007 Share Posted December 18, 2007 (edited) ProcessExists() returns process ID. GetGuiResources requires handle. To get handle, DllCall OpenProcess (as dwDesiredAccess specify PROCESS_QUERY_INFORMATION, bInheritHandle - 0, and dwProcessId - what you get from ProcessExists). Then pass this handle to your GetGuiResources. DllCall CloseHandle when you don't need it, just to be nice. Edited December 18, 2007 by Siao "be smart, drink your wine" Link to comment Share on other sites More sharing options...
L00py Posted December 18, 2007 Author Share Posted December 18, 2007 ProcessExists() returns process ID. GetGuiResources requires handle. To get handle, DllCall OpenProcess (as dwDesiredAccess specify PROCESS_QUERY_INFORMATION, bInheritHandle - 0, and dwProcessId - what you get from ProcessExists). Then pass this handle to your GetGuiResources. DllCall CloseHandle when you don't need it, just to be nice.Heh, in all my searches yesterday, I didn't manage to hit on using OpenProcess to return that handle. Fixed and working now. Thanks! Link to comment Share on other sites More sharing options...
Zedna Posted December 18, 2007 Share Posted December 18, 2007 Heh, in all my searches yesterday, I didn't manage to hit on using OpenProcess to return that handle. Fixed and working now. Thanks!So post fixed working code snippet so others can see all working stuff. Resources UDF Â ResourcesEx UDF Â AutoIt Forum Search Link to comment Share on other sites More sharing options...
rover Posted December 19, 2007 Share Posted December 19, 2007 (edited) I could have used this a few weeks back when I was troubleshooting a GDI leak I resolved with a scripta little more convenient than process explorer took OpenProcess call from _ReduceMemory() UDF by jftuga and wOuterlazy mans process select - arraydisplayselect process from listclick 'Textselected'click 'Close'enjoyEdit: fixed unclosed handlesDisplay GDI and USER handles for current process and selected processexpandcollapse popup#include <Array.au3> #include <GUIConstants.au3> #include <Process.au3> ;Global Const $PROCESS_ALL_ACCESS = 0x1f0fff Global Const $PROCESS_QUERY_INFORMATION = 0x0400 ; comment out for v3.2.9.10 and up ; select single process from list then click 'TextSelected' button, then 'Close' (multiple selected items will be ignored) $alist = ProcessList() _ArraySort($aList, 0, 1, 0, 2, 0) _ArrayDisplay($alist,"Select Process: Click 'TextSelected', Then 'Close'",0,0) $processname = StringSplit(ClipGet(), '|', 1) ClipPut("") Switch IsArray($processname) Case 1 If UBound($processname) = 4 Then $processname = $processname[2] Else ContinueCase EndIf Case 0 $processname = "explorer.exe" Endswitch $ai_GetProcessId = ProcessExists($processname) GUICreate("User & GDI Handles To Objects Count",360,200,-1,-1,BitOR($WS_SYSMENU, $WS_CAPTION),$WS_EX_TOPMOST) $label1 = GUICtrlCreateLabel("Process:",20,20,200,20) $label2 = GUICtrlCreateLabel("GDI Objects:",20,40,120,20) $label3 = GUICtrlCreateLabel("USER objects:",20,60,120,20) $label4 = GUICtrlCreateLabel("Process:",20,100,320,20) $label5 = GUICtrlCreateLabel("GDI Objects:",20,120,120,20) $label6 = GUICtrlCreateLabel("USER objects:",20,140,120,20) GUISetState (@SW_SHOW) ; used for current process, as script or compiled $ai_GetCurrentProcessId = DllCall('kernel32.dll', 'int', 'GetCurrentProcessId') $ai_GetCurrentProcessId = $ai_GetCurrentProcessId[0] $ai_Handle1 = DllCall("kernel32.dll", 'hwnd', 'OpenProcess', 'dword', $PROCESS_QUERY_INFORMATION, 'dword', False, 'dword', $ai_GetCurrentProcessId) If @error Then SetError(1) Exit EndIf ; used for explorer.exe or any process - monitor your script for GDI handle leaks ;$ai_GetProcessId = ProcessExists($processname[2]) ; enter your script exe name $ai_Handle2 = DllCall("kernel32.dll", 'hwnd', 'OpenProcess', 'dword', $PROCESS_QUERY_INFORMATION, 'dword', False, 'dword', $ai_GetProcessId) If @error Then SetError(1) Exit EndIf $timer = TimerInit() While 1 $msg = GUIGetMsg() If TimerDiff($timer) >= 250 Then $GDIcount1 = DllCall("user32.dll", "int", "GetGuiResources", "hwnd", $ai_Handle1[0], "int", 0) $USERcount1 = DllCall("user32.dll", "int", "GetGuiResources", "hwnd", $ai_Handle1[0], "int", 1) $GDIcount2 = DllCall("user32.dll", "int", "GetGuiResources", "hwnd", $ai_Handle2[0], "int", 0) $USERcount2 = DllCall("user32.dll", "int", "GetGuiResources", "hwnd", $ai_Handle2[0], "int", 1) GUICtrlSetData($label1, "Process:"&@TAB&_ProcessGetName($ai_GetCurrentProcessId)&" ") ; 'AutoIt3.exe' if run as script GUICtrlSetData($label2, "GDI Objects:"&@TAB&$GDIcount1[0]) GUICtrlSetData($label3, "USER objects:"&@TAB&$USERcount1[0]) GUICtrlSetData($label4, "Process:"&@TAB&_ProcessGetName($ai_GetProcessId)) GUICtrlSetData($label5, "GDI Objects:"&@TAB&$GDIcount2[0]) GUICtrlSetData($label6, "USER objects:"&@TAB&$USERcount2[0]) $timer = TimerInit() Endif If $msg = $GUI_EVENT_CLOSE Then Exit Wend Func OnAutoItExit() DllCall('kernel32.dll', 'int', 'CloseHandle', 'hwnd', $ai_Handle1[0]) DllCall('kernel32.dll', 'int', 'CloseHandle', 'hwnd', $ai_Handle2[0]) Beep(1000,5) EndFunc Edited December 20, 2007 by rover I see fascists... Link to comment Share on other sites More sharing options...
rover Posted December 19, 2007 Share Posted December 19, 2007 (edited) script is not closing handles, even with int changed to hwnd....closehandle call returning zeroaccording to MSDN should be 'Non-zero'MSDN - Close Handle$ret1 = DllCall('kernel32.dll', 'int', 'CloseHandle', 'hwnd', $ai_Handle1)ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $ret1[0] = ' & $ret1[0] & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console@@ Debug(85) : $ret1[0] = 0 Edited December 19, 2007 by rover I see fascists... Link to comment Share on other sites More sharing options...
piccaso Posted December 19, 2007 Share Posted December 19, 2007 $ai_Handle1 is an array CoProc Multi Process Helper libraryTrashBin.nfshost.com store your AutoIt related files here!AutoIt User Map Link to comment Share on other sites More sharing options...
rover Posted December 19, 2007 Share Posted December 19, 2007 $ai_Handle1 is an array Thanks Picasso, for the extra set of eyes (and brain) missed that, even though I had used $ai_Handle1[0] in the GuiResource call sometimes can't see the trees for the forest... btw, my vote for best CatHead Avatar on the forum Thanks I see fascists... Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now