Leaderboard
Popular Content
Showing content with the highest reputation on 09/04/2025 in all areas
-
Hey mate, Yeah so there's a bit you can do.. _WinAPI_GetWindowFileName calls a few things, which we can streamline if we're planning to call it 10000 times,. Func _WinAPI_GetWindowFileName($hWnd) Local $iPID = 0 Local $aCall = DllCall("user32.dll", "bool", "IsWindow", "hwnd", $hWnd) If $aCall[0] Then $aCall = DllCall("user32.dll", "dword", "GetWindowThreadProcessId", "hwnd", $hWnd, "dword*", 0) $iPID = $aCall[2] EndIf If Not $iPID Then Return SetError(1, 0, '') Local $sResult = _WinAPI_GetProcessFileName($iPID) If @error Then Return SetError(@error, @extended, '') Return $sResult EndFunc Func _WinAPI_GetProcessFileName($iPID = 0) If Not $iPID Then $iPID = @AutoItPID Local $hProcess = DllCall('kernel32.dll', 'handle', 'OpenProcess', 'dword', ((_WinAPI_GetVersion() < 6.0) ? 0x00000410 : 0x00001010), _ 'bool', 0, 'dword', $iPID) If @error Or Not $hProcess[0] Then Return SetError(@error + 20, @extended, '') Local $sPath = _WinAPI_GetModuleFileNameEx($hProcess[0]) Local $iError = @error DllCall("kernel32.dll", "bool", "CloseHandle", "handle", $hProcess[0]) If $iError Then Return SetError(@error, 0, '') Return $sPath EndFunc Func _WinAPI_GetModuleFileNameEx($hProcess, $hModule = 0) Local $aCall = DllCall(@SystemDir & '\psapi.dll', 'dword', 'GetModuleFileNameExW', 'handle', $hProcess, 'handle', $hModule, _ 'wstr', '', 'int', 4096) If @error Or Not $aCall[0] Then Return SetError(@error + 10, @extended, '') Return $aCall[3] EndFunc Firstly I'd be using dll handles with DllOpen instead of using file names in DllCall, this should save open/closing Dlls all the time! That IsWindow call in GetWindowFilename is there as a sanity check. So if you're reasonably happy that you won't sent it rubbish, that can go. GetVersion doesn't need to be called 10000 times. 6.0 is Vista, so we probably don't really care about this anymore... but if you do - just call GetVersion once before your loop, or store it as a static or something. Use GetModuleBaseNameW instead of GetModuleFileNameExW - that will get you just the "notepad.exe" part of the process name We don't need to allocate the string buffer and free it 10000 times either (assuming the func returns a null-terminated string). Create a buffer once beforehand and just reuse it. #include <WinAPISysWin.au3> #include <WinAPIProc.au3> #include <Array.au3> #include <WinAPISys.au3> #include <File.au3> Global $maxruns = 10000 Global $hUser32 = DllOpen('user32.dll') Global $hKernel32 = DllOpen('kernel32.dll') Global $hpsapi = DllOpen('psapi.dll') ; Run Notepad Run("notepad.exe") ; Wait 10 seconds for the Notepad window to appear. WinWait("[CLASS:Notepad]", "", 10) Global $iPID = ProcessExists("notepad.exe") ; Retrieve the handle of the Notepad window using the classname of Notepad. Global $hWnd = WinGetHandle("[CLASS:Notepad]") ConsoleWrite("Notepad handle: " & $hWnd & @CRLF) Example3() Func Example3() Local $hTimer = TimerInit() For $i = 1 To $maxruns Local $test = _WinAPI_GetWindowFileName2($hWnd) Next Local $fDiff = TimerDiff($hTimer) ConsoleWrite("Timer: " & $fDiff & @CRLF) ConsoleWrite("_WinAPI_GetWindowFileName: " & $test & @CRLF) EndFunc Func _WinAPI_GetWindowFileName2($hWnd) Local Static $iNumChars = 512, $tBuff = DllStructCreate(StringFormat("wchar[%d]", $iNumChars)) Local $aCall = DllCall($hUser32, "dword", "GetWindowThreadProcessId", "hwnd", $hWnd, "dword*", 0) Local $iPID = $aCall[2] $aCall = DllCall($hKernel32, 'handle', 'OpenProcess', 'dword', 0x00001010, 'bool', 0, 'dword', $iPID) Local $hProc = $aCall[0] DllCall($hpsapi, 'dword', 'GetModuleBaseNameW', 'handle', $hProc, 'handle', 0, 'struct*', $tBuff, 'int', $iNumChars) $aCall = DllCall($hKernel32, "bool", "CloseHandle", "handle", $hProc) Return DllStructGetData($tBuff, 1) EndFunc Obviously you'll want to put some error checks back in, and clean up when you're done.. but you get the idea Edit: and the time comparison.. Notepad handle: 0x00000000005B0D40 Timer: 548.97 _WinAPI_GetWindowFileName2: Notepad.exe Timer: 1794.9062 _WinAPI_GetWindowFileName: C:\Program Files\WindowsApps\Microsoft.WindowsNotepad_11.2507.26.0_x64__8wekyb3d8bbwe\Notepad\Notepad.exe3 points
-
pixelsearch, analytical and comprehensive as always, thank you very much The solution proposed by Danyfirex š, in this particular post is completely functional #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_UseX64=y #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #include <GuiTab.au3> ;>> Target: C:\Program Files (x86)\AutoIt3\Examples\Helpfile\GUICtrlCreateTab.au3 If Not WinExists("My GUI Tab") Then Exit Local $hWnd = WinWait("My GUI Tab", "", 1) ConsoleWrite("$hWnd=" & $hWnd & @CRLF) Local $hCtrl = ControlGetHandle($hWnd, "", "SysTabControl321") ConsoleWrite("$hCtrl=" & $hCtrl & @CRLF) Local $hParentWnd = _WinAPI_GetParent($hCtrl) ConsoleWrite("$hParentWnd=" & $hParentWnd & @CRLF) ; Show number of tabs Local $iTabCnt = _GUICtrlTab_GetItemCount($hCtrl) ConsoleWrite("Number of tabs: " & $iTabCnt & @CRLF & @CRLF) Local $sItemText, $aItem ; Now is working !! For $x = 0 To $iTabCnt - 1 $aItem = _GUICtrlTab_GetItemEx($hCtrl, $x) $sItemText = $aItem[1] ConsoleWrite("$sItemText=" & $sItemText & @CRLF) Next Func _GUICtrlTab_GetItemEx($hWnd, $iIndex) If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd) Local $tagTCITEMEx = $tagTCITEM & ";ptr Filler" ; strange the Filler is erased by TCM_GETITEM : MS Bug!!! If Not _WinAPI_InProcess($hWnd, $__g_hGUICtrl_LastWnd) Then ;x86 read remote x64 If (Not @AutoItX64) And (Not _WinAPI_IsWow64Process(DllCall("user32.dll", "dword", "GetWindowThreadProcessId", "hwnd", $hWnd, "dword*", 0)[2])) Then $tagTCITEMEx = StringReplace($tagTCITEMEx, "ptr", "INT64") EndIf ;x64 read remote x86 If (@AutoItX64) And (_WinAPI_IsWow64Process(DllCall("user32.dll", "dword", "GetWindowThreadProcessId", "hwnd", $hWnd, "dword*", 0)[2])) Then $tagTCITEMEx = StringReplace($tagTCITEMEx, "ptr", "ULONG") EndIf EndIf Local $tItem = DllStructCreate($tagTCITEMEx) DllStructSetData($tItem, "Mask", $TCIF_ALLDATA) DllStructSetData($tItem, "StateMask", BitOR($TCIS_HIGHLIGHTED, $TCIS_BUTTONPRESSED)) Local $tBuffer, $iMsg If _GUICtrlTab_GetUnicodeFormat($hWnd) Then $tBuffer = $__g_tTabBuffer $iMsg = $TCM_GETITEMW Else $tBuffer = $__g_tTabBufferANSI $iMsg = $TCM_GETITEMA EndIf Local $iRet = __GUICtrl_SendMsg($hWnd, $iMsg, $iIndex, $tItem, $tBuffer, True, 4, True) Local $aItem[4] $aItem[0] = DllStructGetData($tItem, "State") $aItem[1] = DllStructGetData($tBuffer, "Text") $aItem[2] = DllStructGetData($tItem, "Image") $aItem[3] = DllStructGetData($tItem, "Param") Return SetError($iRet = 0, 0, $aItem) EndFunc ;==>_GUICtrlTab_GetItem This way, I avoid having to make a helper script like a bridge, I just add the function. Mission accomplished. Thank you very much3 points
-
Fastest method to get process name from handle
SOLVE-SMART and one other reacted to WildByDesign for a topic
Indeed, yes. My jaw is still on the floor. If this forum has any kind of Solution of the Year, Matty nailed it. As soon as I pick my jaw up from the floor Iām going to respond in more detail.2 points -
Fastest method to get process name from handle
WildByDesign and one other reacted to SOLVE-SMART for a topic
Wow @MattyD, that is impressive. I also played around with some variants but what really did the trick is mentioned by you: My timer result was 980.0433, but you version is way better! I guess this will help @WildByDesign a lot, Best regards Sven2 points -
_GUICtrlTab_GetItemText the target crashes on dissimilar architecture
Danyfirex and one other reacted to pixelsearch for a topic
@ioa747 Hi When you call _GUICtrlTab_GetItemText, then _GUICtrlTab_GetItem is called And _GuiCtrlTab_GetItem had issues as seen on Trac Ticket 3903 and in this post. In the post, @Danyfirex worked on this x86-x64 issue and maybe he could give an advice here if he got time ? Also I notice code in _GUICtrlTab_GetItem has been updated in new release 3.3.17.1 (beta) . Did you check your script with 3.3.17.1 , maybe it's solved with the new release ? Fingers crossed & good luck2 points -
Automating File/Windows Explorer and Desktop
SOLVE-SMART reacted to roob for a topic
@SOLVE-SMART My GitHub account was temporarily suspended for security reasons. I think the issue was caused by Opera VPN, which I sometimes forget to turn off. Anyway, my account is now fully functional. In the meantime, I opened this thread: https://www.autoitscript.com/forum/topic/213109-super-admin-launcher-sal1 point -
Windows Version Detector
argumentum reacted to Trong for a topic
I have released version 2, you might want to try it1 point -
Automating File/Windows Explorer and Desktop
argumentum reacted to roob for a topic
https://www.autoitscript.com/forum/topic/213109-super-admin-launcher-sal1 point -
This is what I meant. Func _GUICtrlTab_GetItem($hWnd, $iIndex) If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd) Local $tagTCITEMEx = $tagTCITEM & ";ptr Filler" ; strange the Filler is erased by TCM_GETITEM : MS Bug!!! If Not _WinAPI_InProcess($hWnd, $__g_hGUICtrl_LastWnd) Then ;x86 read remote x64 If (Not @AutoItX64) And (Not _WinAPI_IsWow64Process(DllCall("user32.dll", "dword", "GetWindowThreadProcessId", "hwnd", $hWnd, "dword*", 0)[2])) Then $tagTCITEMEx = StringReplace($tagTCITEMEx, "ptr", "INT64") EndIf ;x64 read remote x86 If (@AutoItX64) And (_WinAPI_IsWow64Process(DllCall("user32.dll", "dword", "GetWindowThreadProcessId", "hwnd", $hWnd, "dword*", 0)[2])) Then $tagTCITEMEx = StringReplace($tagTCITEMEx, "ptr", "ULONG") EndIf EndIf Local $tItem = DllStructCreate($tagTCITEMEx) DllStructSetData($tItem, "Mask", $TCIF_ALLDATA) DllStructSetData($tItem, "StateMask", BitOR($TCIS_HIGHLIGHTED, $TCIS_BUTTONPRESSED)) Local $tBuffer, $iMsg If _GUICtrlTab_GetUnicodeFormat($hWnd) Then $tBuffer = $__g_tTabBuffer $iMsg = $TCM_GETITEMW Else $tBuffer = $__g_tTabBufferANSI $iMsg = $TCM_GETITEMA EndIf Local $iRet = __GUICtrl_SendMsg($hWnd, $iMsg, $iIndex, $tItem, $tBuffer, True, 4, True) Local $aItem[4] $aItem[0] = DllStructGetData($tItem, "State") $aItem[1] = DllStructGetData($tBuffer, "Text") $aItem[2] = DllStructGetData($tItem, "Image") $aItem[3] = DllStructGetData($tItem, "Param") Return SetError($iRet = 0, 0, $aItem) EndFunc ;==>_GUICtrlTab_GetItem It's a little ugly, it's just to make you see what I meant. Saludos1 point