Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 09/25/2024 in all areas

  1. Hello everybody Now that I have received approval from a moderator [ as there are below some references to the last downloadable source of AutoIt written in C++, version 3.1.0 from 2005 ] then I post this script where I tried to understand what exactly WinKill() is doing, when compared to WinClose() It was interesting to "rewrite" the WinKill function, using the AutoIt functions that match Jon's C++ code. First the C++ code corresponding to WinKill, as found on Stackoverflow site and GitHub /////////////////////////////////////////////////////////////////////////////// // WinKill() // Closes a window - uses more force than WinClose /////////////////////////////////////////////////////////////////////////////// AUT_RESULT AutoIt_Script::F_WinKill(VectorVariant &vParams, Variant &vResult) { Win_WindowSearchInit(vParams); if (Win_WindowSearch() == false) return AUT_OK; // Required window not found Util_WinKill(m_WindowSearchHWND); Util_Sleep(m_nWinWaitDelay); // Briefly pause before continuing return AUT_OK; } // WinKill() /////////////////////////////////////////////////////////////////////////////// // Util_WinKill() // // Closes a window with extreme predjudice // /////////////////////////////////////////////////////////////////////////////// void Util_WinKill(HWND hWnd) { DWORD dwResult; LRESULT lResult = SendMessageTimeout(hWnd, WM_CLOSE, 0, 0, SMTO_ABORTIFHUNG, 500, &dwResult); // wait 500ms if( !lResult ) { // Use more force - Mwuahaha // Get the ProcessId for this window. DWORD pid; GetWindowThreadProcessId( hWnd, &pid ); // Open the process with all access. HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); // Terminate the process. TerminateProcess(hProcess, 0); CloseHandle(hProcess); } } // Util_WinKill() Then the AutoIt script... and its numerous comments #include <APISysConstants.au3> #include <MsgBoxConstants.au3> #include <ProcessConstants.au3> #include <WinAPIProc.au3> #include <WinAPISysWin.au3> #include <WindowsConstants.au3> Example() Func Example() ; Run Notepad Run("notepad.exe") ; Wait 10 seconds for the Notepad window to appear. WinWait("[CLASS:Notepad]", "", 10) ; Retrieve the handle of the Notepad window using the classname of Notepad. Local $hWnd = WinGetHandle("[CLASS:Notepad]") If @error Then MsgBox($MB_TOPMOST, "", "An error occurred when trying to retrieve the window handle of Notepad.") Exit EndIf MsgBox($MB_TOPMOST, "Close me #1", "Before NotePad closure") ; To close NotePad, 3 possible scenarios have been tested below : ;~ ; ======================================================= ;~ ; Close the Notepad window using the handle returned by WinGetHandle. ;~ ; Local $iRet = WinClose($hWnd) ;~ ; ConsoleWrite("WinClose = " & $iRet & @crlf) ;~ ; Or ;~ Local $iRet = _WinAPI_PostMessage($hWnd, $WM_CLOSE, 0, 0) ; as in AutoIt C++ source 3.1.0 "script_win.cpp" part WinClose() ;~ Sleep(250) ; i.e. Util_Sleep(m_nWinWaitDelay) in AutoIt C++ Winclose() source, with m_nWinWaitDelay = 250 in "script.cpp" ;~ ConsoleWrite("_WinAPI_PostMessage = " & $iRet & @crlf) ;~ ; ======================================================= ; ======================================================= ; WinKill($hWnd) ; would be ok but not really recommended as more agressive ; ONE TRY below (succeeded) : let's replace the Winkill() function with the AutoIt functions matching Jon's C++ code : ; see code in AutoIt C++ source 3.1.0 "script_win.cpp" part WinKill() and "utility.cpp" part Util_WinKill() _WinAPI_SendMessageTimeout($hWnd, $WM_CLOSE, 0, 0, 500, $SMTO_ABORTIFHUNG) ; + $SMTO_NOTIMEOUTIFNOTHUNG seems interesting too. ; _WinAPI_SendMessageTimeout is not easy : what is returned is not $aCall[0] but $aCall[7], so we'll check @error and not $aCall[0] ; Test: let's change timeout from 500 to a shorter one (10 or 1), then @error <> 0 and "If $iError Then" part is processed below. ; Test: type something in NotePad, then close the displayed MsgBox : we don't have time to save what was typed : WinKill in action ! Local $iError = @error, $iExtended = @extended ConsoleWrite("_WinAPI_SendMessageTimeout : @error = " & $iError & " @extended = " & $iExtended & @crlf) ConsoleWrite(_WinAPI_GetLastErrorMessage() & @crlf) If $iError Then Local $iPID = 0 Local $iThread = _WinAPI_GetWindowThreadProcessId($hWnd, $iPID) ; no need of $iThread in this script ConsoleWrite("$iPID = " & $iPID & " (0x" & Hex($iPID, 8) & ")" & @crlf) Local $hProcess = _WinAPI_OpenProcess($PROCESS_ALL_ACCESS, False, $iPID) ConsoleWrite("$hProcess = " & $hProcess & @crlf) ; ex. 0x000006B8 ok Local $iRet = _WinAPI_TerminateProcess($hProcess, 0) ConsoleWrite("Terminate Process = " & $iRet & @crlf) ; 1 = ok (Notepad window is no more on screen) Local $iRet = _WinAPI_CloseHandle($hProcess) ConsoleWrite("Close Handle = " & $iRet & @crlf) ; 1 = ok EndIf Sleep(250) ; i.e. Util_Sleep(m_nWinWaitDelay) ; ======================================================= ;~ ; ======================================================= ;~ ; Impossible to use _WinAPI_DestroyWindow because the Notepad window was created in a different thread (msdn & AutoIt helpfile) ;~ Local $iRet = _WinAPI_DestroyWindow($hWnd) ;~ Local $iError = _WinAPI_GetLastError() ;~ Local $iErrMsg = _WinAPI_GetLastErrorMessage() ;~ ConsoleWrite("DestroyWindow = " & $iRet & " $iError = " & $iError & " $iErrMsg = " & $iErrMsg & @crlf) ;~ ; ======================================================= MsgBox($MB_TOPMOST, "Close me #2", "After NotePad was closed") EndFunc ;==>Example ; Personal tests in this script, related to AutoIt C++ source 3.1.0 (2005) , functions WinClose & WinKill ; 1) First link found at Stackoverflow : ; https://stackoverflow.com/questions/32336995/winkill-source-code ; 2) Second link (indicated by the Stackoverflow post) concerns GitHub : ; https://github.com/ellysh/au3src/ ; 3) Interesting discussion in the link below, concerning _WinAPI_SendMessageTimeout : ; "What happens if the timeout occurs at the very moment the message is still processing ? ; https://comp.os.ms-windows.programmer.win32.narkive.com/y5Xv3I7v/sendmessagetimeout-what-happens-if-timeout-occurs The _WinAPI_SendMessageTimeout function (found in the include file WinAPISysWin.au3) was a bit tricky, as it returns $aCall[7] and not $aCall[0] so @error was the key to know what to do on Return It was interesting for me to learn some new functions this way, hoping it will be same for the interested users.
    1 point
  2. Jos

    AutoIt include folder

    Did you try to get that answered? ;-)
    1 point
  3. I've ported some of the JavaScript 140 Bytes demos from dwitter.net to FreeBasic. Download AiO with 1000 examples (7-Zip archive): The beauty - magic of math Vol. 1 - 23 build 2024-01-14.7z (5.09 mb with source code and Windows x64 compiled executables) or have a look to my 1drive folder: _dwitter.net Some screenshots: ... Autoit is too slow for almost all of these examples. Happy watching.
    1 point
  4. Have a look at Arrays in the AutoIt help file. Move your data to a 2-dimensional array and you can loop throug the rows and columns like in Excel. The following code is syntactically correct, but untested. #include <Array.au3> ; ----------------------------------------------- Opt("MustDeclareVars", 1) ; ----------------------------------------------- _VerifyRegistration() ; ----------------------------------------------- Func _VerifyRegistration() ; Source data Local $iNumberOfApps = 4, $iFieldsPerApp = 5 ; Array holding the following data in columns for eaqch record: 0=Appname, 1=RegKeyname, 2=RegIndexValue, 3=RegValue, 4=RegValueString Local $aApps[$iNumberOfApps][$iFieldsPerApp] = [ _ ["Gutar Rig 5", "HKEY_LOCAL_MACHINE\SOFTWARE\Native Instruments\Guitar Rig 5", 7], _ ["Rammfire", "HKEY_LOCAL_MACHINE\Software\Native Instruments\Rammfire", 4], _ ["Reflektor", "HKEY_LOCAL_MACHINE\Software\Native Instruments\Reflektor", 4], _ ["Traktors 12","HKEY_LOCAL_MACHINE\Software\Native Instruments\Traktors 12", 4] _ ] Local $sMessage = "Start" & @CRLF & @CRLF For $i = 0 To $iNumberOfApps - 1 $aApps[$i][3] = RegEnumVal($aApps[$i][1], $aApps[$i][2]) $aApps[$i][4] = RegRead($aApps[$i][1], $aApps[$i][3]) If $aApps[$i][4] = "00000000000000000000000000000000" Then ; If the $String [IS 0's], then Not Good! $sMessage &= "The App... [" & $aApps[$i][0] & "] ...did not register correctly!" & @CRLF Else ; If the $String [IS NOT 0's], then Good! $sMessage &= "The App... [" & $aApps[$i][0] & "] ...did register correctly!" & @CRLF EndIf ; ----------------------------------------------- Next _ArrayDisplay($aApps) ; ----------------------------------------------- ; ----------------------------------------------- $sMessage &= @CRLF & "End" & @CRLF ; ----------------------------------------------- SplashTextOn("NOTICE!!", $sMessage, 450, 215, -1, -1, 4, "FuturaBQ-DemiBold", 14) Sleep(2000) SplashOff() EndFunc ;==>_VerifyRegistration ; -----------------------------------------------
    1 point
  5. No, it does not need to be installed. @AutoItExe will will resolved to the FullPath of the executed script, once it is compiled.
    1 point
  6. the first two calls are to demonstrate how to call _ArrayDisplayEx() ; with out $iTimeout Ordinary Array Display _ArrayDisplayEx($aArray, "Ordinary Array Display") Sleep(2000) ; with $iTimeout 3second Array Display _ArrayDisplayEx($aArray, "3second Array Display", 3)
    1 point
  7. Unsure if this is intended, but as some of you noticed chromedriver now tries to use a random port on opening. You can override that by supplying the desired port number as a parameter -- _WD_Option('DriverParams', '--port=9515 --verbose --log-path="' & @ScriptDir & '\chrome.log"')
    1 point
×
×
  • Create New...