Ascend4nt Posted March 3, 2009 Share Posted March 3, 2009 (edited) Hi, for the life of me I can't seem to get the below code to work, aside from giving me a list of PDH Query Path Objects. The PDHQueryHandle returned by the 'PdhOpenQueryW' function returns fine, but as soon as I try to *use* the handle, it gives me the error code that the handle is invalid! WTH?Can someone verify the same behavior for me? Or point out a stupid mistake I may have made?Thanks!Ascend4ntP.S. MSDN Link: Using the PDH Functions to Consume Counter Data*EDIT: Oops, in my rush to copy and paste, I forgot one crucial line ($sCounterPath)*EDIT2: Fix found (thx Manko) - though source is not updated. A UDF will be released hopefully soon incorporating the fixes (see DLLOpen/Close recommendation), as well as including actual functionality! expandcollapse popup#include <Array.au3> Local $sCounterPath="\Process(*)\% Processor Time" Local $hPDHQueryHandle ; PdhOpenQuery: Create a PDH Query Handle Local $aRet=DllCall("pdh.dll","long","PdhOpenQueryW","ptr",0,"dword*",0,"ptr*",$hPDHQueryHandle) ; Error? If @error Or Not IsArray($aRet) Or $aRet[0] Then Exit ; DEBUG: Return info ConsoleWrite("1st PDH Call succeeded, return:" &$aRet[0]&",param1:"&$aRet[1]&",param2:"&$aRet[2]&",handle:" & $aRet[3] & @CRLF) ; Copy handle $hPDHQueryHandle=$aRet[3] Local $iBufSize ; 1st call - get buffer size $aRet=DllCall("pdh.dll","long","PdhExpandWildCardPathW","ptr",ChrW(0),"wstr",$sCounterPath,"ptr",ChrW(0),"dword*",$iBufSize,"dword",0) ; Return should be PDH_MORE_DATA (0x800007D2) If @error Or Not IsArray($aRet) Or $aRet[0]<>0x800007D2 Then ; Close PDH Query Handle DllCall("pdh.dll","long","PdhCloseQuery","ptr",$hPDHQueryHandle) Exit EndIf ; Get required buffer size $iBufSize=$aRet[4] ; DEBUG ConsoleWrite("BufSize required:" & $iBufSize & @CRLF) ; Setup a buffer (ubytes because pulling a multi-NULL-terminated Unicode string out is impossible with wchars) Local $stExpandedPathList=DllStructCreate("ubyte["&($iBufSize*2)&']') ; 2nd call - fill buffer with expanded PDH Paths $aRet=DllCall("pdh.dll","long","PdhExpandWildCardPathW","ptr",ChrW(0),"wstr",$sCounterPath, _ "ptr",DllStructGetPtr($stExpandedPathList),"dword*",$iBufSize,"dword",0) ; Error? If @error Or Not IsArray($aRet) Or $aRet[0] Then ; Close PDH Query Handle DllCall("pdh.dll","long","PdhCloseQuery","ptr",$hPDHQueryHandle) Exit EndIf ; DEBUG INFO ConsoleWrite("Call successful, Bufsize=" & $aRet[4]&", Expanded Path List w\ len:" & _ StringLen(BinaryToString(DllStructGetData($stExpandedPathList,1),2))&@CRLF&"Contents:" & @CRLF) ; GET UNICODE STRING, SPLIT BY NULL-TERMS INTO ARRAY Local $ahPDHCounterHandle,$aPDHProcessList=StringSplit(BinaryToString(DllStructGetData($stExpandedPathList,1),2),ChrW(0),1) ; Now to go through and add them one by one to the PDH Query Handle If IsArray($aPDHProcessList) Then ; Last split is probably at the double-NULL term, so remove the last element and decrease count If $aPDHProcessList[$aPDHProcessList[0]]=="" Then ReDim $aPDHProcessList[$aPDHProcessList[0]] $aPDHProcessList[0]-=1 EndIf ; DEBUG: Show PDH Process List (as split) _ArrayDisplay($aPDHProcessList,"PDH Process List") ; Set size of Counter Handles to the same size as the PDH Process List Dim $ahPDHCounterHandle[$aPDHProcessList[0]+1] ; Equalize Bottom element (count) $ahPDHCounterHandle[0]=$aPDHProcessList[0] ; Iterate through array For $i=1 to $aPDHProcessList[0] ; DEBUG ConsoleWrite("Handle (" &$hPDHQueryHandle&") Adding:" &$aPDHProcessList[$i] & @CRLF) ; DEBUG CALL - Validate Path. Works! Argh ;$aRet=DllCall("pdh.dll","long","PdhValidatePathW","wstr",$aPDHProcessList[$i]) ;If IsArray($aRet) And Not $aRet[0] Then ConsoleWrite("Path validated!" & @CRLF) ; ADD COUNTER CALL - CONSISTENT ERRORS! ARGH. ; (err code is INVALID HANDLE) $aRet=DllCall("pdh.dll","long","PdhAddCounterW","ptr",$hPDHQueryHandle,"wstr",$aPDHProcessList[$i],"dword*",$i,"ptr*",$ahPDHCounterHandle[$i]) If @error Or Not IsArray($aRet) Or $aRet[0] Then ; Return code C0000BBC = INVALID HANDLE. WHY?!?! ; Technically this could throw an error since $aRet might not be an array.. but here for DEBUG info ConsoleWrite("Ret:" & Hex($aRet[0]) & @CRLF) ; Close PDH Query Handle $aRet=DllCall("pdh.dll","long","PdhCloseQuery","ptr",$hPDHQueryHandle) ; Technically not a good idea since $aRet might not be an array.. but here for DEBUG info ConsoleWrite("Ret:" & Hex($aRet[0]) & @CRLF) Exit EndIf Next EndIf ; Close PDH Query Handle DllCall("pdh.dll","long","PdhCloseQuery","ptr",$hPDHQueryHandle) Edited March 3, 2009 by ascendant My contributions: Performance Counters in Windows - Measure CPU, Disk, Network etc Performance | Network Interface Info, Statistics, and Traffic | CPU Multi-Processor Usage w/o Performance Counters | Disk and Device Read/Write Statistics | Atom Table Functions | Process, Thread, & DLL Functions UDFs | Process CPU Usage Trackers | PE File Overlay Extraction | A3X Script Extract | File + Process Imports/Exports Information | Windows Desktop Dimmer Shade | Spotlight + Focus GUI - Highlight and Dim for Eyestrain Relief | CrossHairs (FullScreen) | Rubber-Band Boxes using GUI's (_GUIBox) | GUI Fun! | IE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) | Magnifier (Vista+) Functions UDF | _DLLStructDisplay (Debug!) | _EnumChildWindows (controls etc) | _FileFindEx | _ClipGetHTML | _ClipPutHTML + ClipPutHyperlink | _FileGetShortcutEx | _FilePropertiesDialog | I/O Port Functions | File(s) Drag & Drop | _RunWithReducedPrivileges | _ShellExecuteWithReducedPrivileges | _WinAPI_GetSystemInfo | dotNETGetVersions | Drive(s) Power Status | _WinGetDesktopHandle | _StringParseParameters | Screensaver, Sleep, Desktop Lock Disable | Full-Screen Crash Recovery Wrappers/Modifications of others' contributions: _DOSWildcardsToPCRegEx (original code: RobSaunder's) | WinGetAltTabWinList (original: Authenticity) UDF's added support/programming to: _ExplorerWinGetSelectedItems | MIDIEx UDF (original code: eynstyne) (All personal code/wrappers centrally located at Ascend4nt's AutoIT Code) Link to comment Share on other sites More sharing options...
martin Posted March 3, 2009 Share Posted March 3, 2009 (edited) Hi, for the life of me I can't seem to get the below code to work, aside from giving me a list of PDH Query Path Objects. The PDHQueryHandle returned by the 'PdhOpenQueryW' function returns fine, but as soon as I try to *use* the handle, it gives me the error code that the handle is invalid! WTH? Can someone verify the same behavior for me? Or point out a stupid mistake I may have made? Thanks! Ascend4nt P.S. MSDN Link: Using the PDH Functions to Consume Counter Data expandcollapse popup#include <Array.au3> Local $hPDHQueryHandle ; PdhOpenQuery: Create a PDH Query Handle Local $aRet=DllCall("pdh.dll","long","PdhOpenQueryW","ptr",0,"dword*",0,"ptr*",$hPDHQueryHandle) ; Error? If @error Or Not IsArray($aRet) Or $aRet[0] Then Exit ; DEBUG: Return info ConsoleWrite("1st PDH Call succeeded, return:" &$aRet[0]&",param1:"&$aRet[1]&",param2:"&$aRet[2]&",handle:" & $aRet[3] & @CRLF) ; Copy handle $hPDHQueryHandle=$aRet[3] Local $iBufSize ; 1st call - get buffer size $aRet=DllCall("pdh.dll","long","PdhExpandWildCardPathW","ptr",ChrW(0),"wstr",$sCounterPath,"ptr",ChrW(0),"dword*",$iBufSize,"dword",0) ; Return should be PDH_MORE_DATA (0x800007D2) If @error Or Not IsArray($aRet) Or $aRet[0]<>0x800007D2 Then ; Close PDH Query Handle DllCall("pdh.dll","long","PdhCloseQuery","ptr",$hPDHQueryHandle) Exit EndIf ; Get required buffer size $iBufSize=$aRet[4] ; DEBUG ConsoleWrite("BufSize required:" & $iBufSize & @CRLF) ; Setup a buffer (ubytes because pulling a multi-NULL-terminated Unicode string out is impossible with wchars) Local $stExpandedPathList=DllStructCreate("ubyte["&($iBufSize*2)&']') ; 2nd call - fill buffer with expanded PDH Paths $aRet=DllCall("pdh.dll","long","PdhExpandWildCardPathW","ptr",ChrW(0),"wstr",$sCounterPath, _ "ptr",DllStructGetPtr($stExpandedPathList),"dword*",$iBufSize,"dword",0) ; Error? If @error Or Not IsArray($aRet) Or $aRet[0] Then ; Close PDH Query Handle DllCall("pdh.dll","long","PdhCloseQuery","ptr",$hPDHQueryHandle) Exit EndIf ; DEBUG INFO ConsoleWrite("Call successful, Bufsize=" & $aRet[4]&", Expanded Path List w\ len:" & _ StringLen(BinaryToString(DllStructGetData($stExpandedPathList,1),2))&@CRLF&"Contents:" & @CRLF) ; GET UNICODE STRING, SPLIT BY NULL-TERMS INTO ARRAY Local $ahPDHCounterHandle,$aPDHProcessList=StringSplit(BinaryToString(DllStructGetData($stExpandedPathList,1),2),ChrW(0),1) ; Now to go through and add them one by one to the PDH Query Handle If IsArray($aPDHProcessList) Then ; Last split is probably at the double-NULL term, so remove the last element and decrease count If $aPDHProcessList[$aPDHProcessList[0]]=="" Then ReDim $aPDHProcessList[$aPDHProcessList[0]] $aPDHProcessList[0]-=1 EndIf ; DEBUG: Show PDH Process List (as split) _ArrayDisplay($aPDHProcessList,"PDH Process List") ; Set size of Counter Handles to the same size as the PDH Process List Dim $ahPDHCounterHandle[$aPDHProcessList[0]+1] ; Equalize Bottom element (count) $ahPDHCounterHandle[0]=$aPDHProcessList[0] ; Iterate through array For $i=1 to $aPDHProcessList[0] ; DEBUG ConsoleWrite("Handle (" &$hPDHQueryHandle&") Adding:" &$aPDHProcessList[$i] & @CRLF) ; DEBUG CALL - Validate Path. Works! Argh ;$aRet=DllCall("pdh.dll","long","PdhValidatePathW","wstr",$aPDHProcessList[$i]) ;If IsArray($aRet) And Not $aRet[0] Then ConsoleWrite("Path validated!" & @CRLF) ; ADD COUNTER CALL - CONSISTENT ERRORS! ARGH. ; (err code is INVALID HANDLE) $aRet=DllCall("pdh.dll","long","PdhAddCounterW","ptr",$hPDHQueryHandle,"wstr",$aPDHProcessList[$i],"dword*",$i,"ptr*",$ahPDHCounterHandle[$i]) If @error Or Not IsArray($aRet) Or $aRet[0] Then ; Return code C0000BBC = INVALID HANDLE. WHY?!?! ; Technically this could throw an error since $aRet might not be an array.. but here for DEBUG info ConsoleWrite("Ret:" & Hex($aRet[0]) & @CRLF) ; Close PDH Query Handle $aRet=DllCall("pdh.dll","long","PdhCloseQuery","ptr",$hPDHQueryHandle) ; Technically not a good idea since $aRet might not be an array.. but here for DEBUG info ConsoleWrite("Ret:" & Hex($aRet[0]) & @CRLF) Exit EndIf Next EndIf ; Close PDH Query Handle DllCall("pdh.dll","long","PdhCloseQuery","ptr",$hPDHQueryHandle) Should PdhExpandWildCardPathW be PdhExpandWildCardPathH? Edited March 3, 2009 by martin Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script. Link to comment Share on other sites More sharing options...
Ascend4nt Posted March 3, 2009 Author Share Posted March 3, 2009 Should PdhExpandWildCardPathW be PdhExpandWildCardPathH?No, that would be used for log files. Anyway, the handle isn't used for that function, and works fine as it is (see the results in _ArrayDisplay()). Thanks for trying though My contributions: Performance Counters in Windows - Measure CPU, Disk, Network etc Performance | Network Interface Info, Statistics, and Traffic | CPU Multi-Processor Usage w/o Performance Counters | Disk and Device Read/Write Statistics | Atom Table Functions | Process, Thread, & DLL Functions UDFs | Process CPU Usage Trackers | PE File Overlay Extraction | A3X Script Extract | File + Process Imports/Exports Information | Windows Desktop Dimmer Shade | Spotlight + Focus GUI - Highlight and Dim for Eyestrain Relief | CrossHairs (FullScreen) | Rubber-Band Boxes using GUI's (_GUIBox) | GUI Fun! | IE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) | Magnifier (Vista+) Functions UDF | _DLLStructDisplay (Debug!) | _EnumChildWindows (controls etc) | _FileFindEx | _ClipGetHTML | _ClipPutHTML + ClipPutHyperlink | _FileGetShortcutEx | _FilePropertiesDialog | I/O Port Functions | File(s) Drag & Drop | _RunWithReducedPrivileges | _ShellExecuteWithReducedPrivileges | _WinAPI_GetSystemInfo | dotNETGetVersions | Drive(s) Power Status | _WinGetDesktopHandle | _StringParseParameters | Screensaver, Sleep, Desktop Lock Disable | Full-Screen Crash Recovery Wrappers/Modifications of others' contributions: _DOSWildcardsToPCRegEx (original code: RobSaunder's) | WinGetAltTabWinList (original: Authenticity) UDF's added support/programming to: _ExplorerWinGetSelectedItems | MIDIEx UDF (original code: eynstyne) (All personal code/wrappers centrally located at Ascend4nt's AutoIT Code) Link to comment Share on other sites More sharing options...
martin Posted March 3, 2009 Share Posted March 3, 2009 No, that would be used for log files. Anyway, the handle isn't used for that function, and works fine as it is (see the results in _ArrayDisplay()). Thanks for trying though Ok.I didn't see the output of _ArrayDisplay because the code you posted doesn't run, so I was just guessing. Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script. Link to comment Share on other sites More sharing options...
Ascend4nt Posted March 3, 2009 Author Share Posted March 3, 2009 martin, sorry about that! - I screwed up and forgot one line (Local $sCounterPath="\Process(*)\% Processor Time"). I added it to the 1st post. It should run now - but you'll see by the console messages/comments what's the matter thx My contributions: Performance Counters in Windows - Measure CPU, Disk, Network etc Performance | Network Interface Info, Statistics, and Traffic | CPU Multi-Processor Usage w/o Performance Counters | Disk and Device Read/Write Statistics | Atom Table Functions | Process, Thread, & DLL Functions UDFs | Process CPU Usage Trackers | PE File Overlay Extraction | A3X Script Extract | File + Process Imports/Exports Information | Windows Desktop Dimmer Shade | Spotlight + Focus GUI - Highlight and Dim for Eyestrain Relief | CrossHairs (FullScreen) | Rubber-Band Boxes using GUI's (_GUIBox) | GUI Fun! | IE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) | Magnifier (Vista+) Functions UDF | _DLLStructDisplay (Debug!) | _EnumChildWindows (controls etc) | _FileFindEx | _ClipGetHTML | _ClipPutHTML + ClipPutHyperlink | _FileGetShortcutEx | _FilePropertiesDialog | I/O Port Functions | File(s) Drag & Drop | _RunWithReducedPrivileges | _ShellExecuteWithReducedPrivileges | _WinAPI_GetSystemInfo | dotNETGetVersions | Drive(s) Power Status | _WinGetDesktopHandle | _StringParseParameters | Screensaver, Sleep, Desktop Lock Disable | Full-Screen Crash Recovery Wrappers/Modifications of others' contributions: _DOSWildcardsToPCRegEx (original code: RobSaunder's) | WinGetAltTabWinList (original: Authenticity) UDF's added support/programming to: _ExplorerWinGetSelectedItems | MIDIEx UDF (original code: eynstyne) (All personal code/wrappers centrally located at Ascend4nt's AutoIT Code) Link to comment Share on other sites More sharing options...
Manko Posted March 3, 2009 Share Posted March 3, 2009 (edited) Hi!Dll get's loaded and unloaded at every call, maybe it's as sugested in below URL, handle becomes invalid if you don't keep dll loaded?http://www.autohotkey.com/forum/topic17831.html - It just had to be autohotkey?! Now I get "C0000BB9" on the add counter thingy... 0xC0000BB9 (PDH_CSTATUS_NO_COUNTER) The specified counter could not be found.and "00000000" on the closequerything. Progress! Status ok, I guess. /Manko [EDIT: Tried myself...] Edited March 3, 2009 by Manko Yes i rush things! (I sorta do small bursts inbetween doing nothing.) Things I have rushed and reRushed:* ProDLLer - Process manager - Unload viri modules (dll) and moore...* _WinAPI_ProcessListOWNER_WTS() - Get Processes owner list...* _WinAPI_GetCommandLineFromPID() - Get commandline of target process...* _WinAPI_ThreadsnProcesses() Much info if expanded - optional Indented "Parent/Child"-style Processlist. Moore to come... eventually... Link to comment Share on other sites More sharing options...
Ascend4nt Posted March 3, 2009 Author Share Posted March 3, 2009 (edited) Manko, I knew you were the man!! Wow, how about that.. I never even thought about the handle becoming invalid by not explicitly loading the DLL. With the DLLOpen/Close, the function works now - so far Now to see what I can get this puppy to do.. *edit: hmm.. don't know why you're seeing the errors, I haven't now that I use the DLL handle.. but I'll work on the code and release it when I've made it actually do something useful Edited March 3, 2009 by ascendant My contributions: Performance Counters in Windows - Measure CPU, Disk, Network etc Performance | Network Interface Info, Statistics, and Traffic | CPU Multi-Processor Usage w/o Performance Counters | Disk and Device Read/Write Statistics | Atom Table Functions | Process, Thread, & DLL Functions UDFs | Process CPU Usage Trackers | PE File Overlay Extraction | A3X Script Extract | File + Process Imports/Exports Information | Windows Desktop Dimmer Shade | Spotlight + Focus GUI - Highlight and Dim for Eyestrain Relief | CrossHairs (FullScreen) | Rubber-Band Boxes using GUI's (_GUIBox) | GUI Fun! | IE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) | Magnifier (Vista+) Functions UDF | _DLLStructDisplay (Debug!) | _EnumChildWindows (controls etc) | _FileFindEx | _ClipGetHTML | _ClipPutHTML + ClipPutHyperlink | _FileGetShortcutEx | _FilePropertiesDialog | I/O Port Functions | File(s) Drag & Drop | _RunWithReducedPrivileges | _ShellExecuteWithReducedPrivileges | _WinAPI_GetSystemInfo | dotNETGetVersions | Drive(s) Power Status | _WinGetDesktopHandle | _StringParseParameters | Screensaver, Sleep, Desktop Lock Disable | Full-Screen Crash Recovery Wrappers/Modifications of others' contributions: _DOSWildcardsToPCRegEx (original code: RobSaunder's) | WinGetAltTabWinList (original: Authenticity) UDF's added support/programming to: _ExplorerWinGetSelectedItems | MIDIEx UDF (original code: eynstyne) (All personal code/wrappers centrally located at Ascend4nt's AutoIT Code) Link to comment Share on other sites More sharing options...
Manko Posted March 3, 2009 Share Posted March 3, 2009 Manko, I knew you were the man!! Wow, how about that.. I never even thought about the handle becoming invalid by not explicitly loading the DLL.With the DLLOpen/Close, the function works now - so far Now to see what I can get this puppy to do.. *edit: hmm.. don't know why you're seeing the errors, I haven't now that I use the DLL handle.. but I'll work on the code and release it when I've made it actually do something usefulGreAT!!(Dont forget to rename this thread as solved.) /Manko Yes i rush things! (I sorta do small bursts inbetween doing nothing.) Things I have rushed and reRushed:* ProDLLer - Process manager - Unload viri modules (dll) and moore...* _WinAPI_ProcessListOWNER_WTS() - Get Processes owner list...* _WinAPI_GetCommandLineFromPID() - Get commandline of target process...* _WinAPI_ThreadsnProcesses() Much info if expanded - optional Indented "Parent/Child"-style Processlist. Moore to come... eventually... 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