Leaderboard
Popular Content
Showing content with the highest reputation on 01/18/2025 in all areas
-
_RunWaitEx() UDF
SOLVE-SMART and one other reacted to argumentum for a topic
,,in the help area I gave some advice and oops !, ..it works for me because I extended the code but did not share it 😅 So here is the extended code that I call "UDF". Is not up to AutoIt UDF standards but, it runs. ( anyone willing to bring it up to standards, I'll edit this and place your version 😇 ) and here is the demo code #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_AU3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #AutoIt3Wrapper_Run_Au3Stripper=y #Au3Stripper_Parameters=/sv /rm #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #cs ---------------------------------------------------------------------------- AutoIt Version: 3.3.16.1 #ce ---------------------------------------------------------------------------- ; Script Start - Add your code below here #include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include "_RunWaitEx.au3" ; https://www.autoitscript.com/forum/topic/212643-_runwaitex-udf/ ConsoleWriteWLineNumber('Version: ' & _RunWaitEx_Version() & @TAB & @error & @TAB & @extended & @CRLF) ;--- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- Example_InTheLoop() Func Example_InTheLoop() ConsoleWrite(@CRLF & '+ Example_InTheLoop' & @CRLF & @CRLF) ConsoleWriteWLineNumber('DefaultLoopFunc: "' & _RunWaitEx_DefaultLoopFunc() & '"' & @TAB & @error & @TAB & @extended & @CRLF) ConsoleWriteWLineNumber('DefaultLoopFunc: "' & _RunWaitEx_DefaultLoopFunc(Example_InTheLoop) & '"' & @TAB & @error & @TAB & @extended & @CRLF) ConsoleWriteWLineNumber('DefaultLoopFunc: "' & _RunWaitEx_DefaultLoopFunc() & '"' & @TAB & @error & @TAB & @extended & @CRLF) ConsoleWriteWLineNumber('DefaultLoopFunc: "' & _RunWaitEx_DefaultLoopFunc("") & '"' & @TAB & @error & @TAB & @extended & @CRLF) ConsoleWriteWLineNumber('DefaultLoopFunc: "' & _RunWaitEx_DefaultLoopFunc() & '"' & @TAB & @error & @TAB & @extended & @CRLF) ConsoleWriteWLineNumber('DefaultLoopFunc: "' & _RunWaitEx_DefaultLoopFunc("Example_InTheLoop") & '"' & @TAB & @error & @TAB & @extended & @CRLF) ;~ ConsoleWriteWLineNumber('DefaultLoopFunc: "' & _RunWaitEx_DefaultLoopFunc(DontExtst) & '"' & @TAB & @error & @TAB & @extended & @CRLF) ConsoleWriteWLineNumber('DefaultLoopFunc: "' & _RunWaitEx_DefaultLoopFunc(MyLoopOrYours) & '"' & @TAB & @error & @TAB & @extended & @CRLF) ConsoleWriteWLineNumber('DefaultLoopFunc: "' & _RunWaitEx_DefaultLoopFunc() & '"' & @TAB & @error & @TAB & @extended & @CRLF) _RunWaitEx("Dir") _RunWaitEx_DefaultLoopFunc("") EndFunc ;==>Example_InTheLoop Func MyLoopOrYours($WhateverYouMayUseThisFor, $sStringFromCmdLine = "") ; the func needs to have 2 parameters #forceref $WhateverYouMayUseThisFor ConsoleWriteWLineNumber('' & @MIN & ':' & @SEC & '.' & @MSEC & @TAB & $sStringFromCmdLine & @CRLF) ;~ ProcessClose(_RunWaitEx_Last_iPID()) ;~ _RunWaitEx_ProcessClose(1) ; ..remember to set to zero afterwards EndFunc ;==>MyLoopOrYours ;--- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- Example_InTheEditCtrl() Func Example_InTheEditCtrl() ConsoleWrite(@CRLF & '+ Example_InTheEditCtrl' & @CRLF & @CRLF) Local $iW = 600, $iH = 400 Local $hGUI = GUICreate("Example_InTheEditCtrl", $iW, $iH, -1, -1, BitOR($GUI_SS_DEFAULT_GUI, $WS_MAXIMIZEBOX, $WS_SIZEBOX, $WS_THICKFRAME, $WS_TABSTOP)) Local $idEdit = GUICtrlCreateEdit("", 0, 0, $iW, $iH) GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKRIGHT + $GUI_DOCKTOP + $GUI_DOCKBOTTOM) GUISetState(@SW_SHOW) ConsoleWriteWLineNumber('DefaultConsoleWrite: "' & _RunWaitEx_DefaultConsoleWrite() & '"' & @TAB & @error & @TAB & @extended & @CRLF) ConsoleWriteWLineNumber('DefaultConsoleWrite: "' & _RunWaitEx_DefaultConsoleWrite(0) & '"' & @TAB & @error & @TAB & @extended & @CRLF) ConsoleWriteWLineNumber('DefaultCtrlEdit: "' & _RunWaitEx_DefaultCtrlEdit() & '"' & @TAB & @error & @TAB & @extended & @CRLF) ConsoleWriteWLineNumber('DefaultCtrlEdit: "' & _RunWaitEx_DefaultCtrlEdit($idEdit) & '"' & @TAB & @error & @TAB & @extended & @CRLF) ConsoleWriteWLineNumber('DefaultCtrlEdit: "' & _RunWaitEx_DefaultCtrlEdit() & '"' & @TAB & @error & @TAB & @extended & @CRLF) ; ..remember to set to zero afterwards _RunWaitEx("Dir") While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE GUIDelete($hGUI) ExitLoop EndSwitch WEnd EndFunc ;==>Example_InTheEditCtrl ;--- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- Func ConsoleWriteWLineNumber($sStr, $iLine = @ScriptLineNumber, $iError = @error, $iExtended = @extended) Local $iRet = ConsoleWrite('@@ (' & $iLine & ') : ' & $sStr) Return SetError($iError, $iExtended, $iRet) EndFunc ;==>ConsoleWriteWLineNumber so @daledale , please pardon my oops. On the bright side, you may find this ( what I meant ) useful, and hope it serves you in your project PS: there may be some comments that were true in the original snippet but not longer true/relevant. This is a spur-of-the-moment kind of post. Do uncomment and re-comment lines to mess with it, as a learning tool. You're gonna have to read the UDF to know what functions are available ( given my laziness ).2 points -
There is a stringleft (as I didn't want to show everything on every cycle). Remove the stringleft and you will be fine !1 point
-
@daledale I think your issue comes from the fact that you are not waiting for the stream to be ready to transmit correctly. You should wait for the process to be up and running before reading the stream. Here the right way to get the result of ipconfig. #include <Date.au3> #include <Constants.au3> Local $pid, $line While True ConsoleWrite('1 ' & _NowTime() & @CRLF) $pid = Run("ipconfig", "", @SW_HIDE, $STDERR_MERGED) ConsoleWrite('2 ' & _NowTime() & @CRLF) ProcessWaitClose($pid) $line = StdoutRead($pid) ConsoleWrite('3 ' & _NowTime() & StringLeft($line, 50) & @CRLF) ;If StringInStr($line, '0.1' & @CRLF) > 1 Then TraySetIcon("icon1.ico") ;If StringInStr($line, '0.2' & @CRLF) > 1 Then TraySetIcon("icon2.ico") ConsoleWrite('4 ' & _NowTime() & @CRLF) Sleep(2000) ; reduced sleep to get more occurences ConsoleWrite('5 ' & _NowTime() & @CRLF) WEnd1 point
-
1 point
-
Autoit sometimes freezes when polling StdOutRead
daledale reacted to argumentum for a topic
Am using _RunWaitEx() and uses Sleep(1). Running _RunWaitEx('tasklist.exe') as the example and no problems. Give it a try ? it does use ternary operators so, replace with _Iif() if v3.3.14 does not understand/have ternary operators. Am using v3.3.16.11 point -
On my Celeron notebook....slow On my 10900k pc.....fast Really depends on the hardware involved, cpu speed, disk speed, ram speed.1 point
-
Autoit sometimes freezes when polling StdOutRead
argumentum reacted to daledale for a topic
Sorry for my English, translated by Google. Search for the error of Autoit freezing with the operator "stdoutread"brought me to this topic. What can I say, but first about my configuration: Autoit 3.3.14 Win7x64 CPU Core-i7 CPU, 32Gb RAM Approximately the following program code froze for me. I became interested in the reasons. After each of the key operators, I put the so-called marks in the form of console and found that the freezing occurs quite quickly from 10 minutes to 1 hour in the inner loop (where the operator is stdoutread). In the example above, the inner loop is the Do/Until operators. In general, I will not keep you in suspense - I am not 100% sure yet, but my problem was solved* by inserting the Sleep(20) delay into this inner loop. Yes, I will immediately make a reservation - the Sleep delay in the external operator (in the example, it is While/Wend) was initially set for me, I needed it for my purposes and the delay was 20 seconds. Sleep(20000), but it did not help to get rid of the freezes. * - At least I assume and hope so, because more than 2 hours have passed and in my case there are 437 iterations and no freezes. By the way, I draw attention to this quote: "The important part here is the Sleep (200) just after the Run('tasklist.exe") line " and I repeat the operator sleep, which is mentioned in the quote, was initially in the outer loop and this did not help to solve the problem. The problem was solved precisely by the fact that the operator sleep was located in the inner loop (Between Do/Until in Example above)1 point -
I need from from time to time to run small processes to perform task that would otherwise clog the main process. Yes, there is a number of other UDF that could have done it very well, but I felt they were an over-kill for what I wanted. Don't throw me stones, I know it's not really multi-threading, but it is as close as I could get with simple AutoIt. If someone wonders why I called it PMT, the P stands for Pretending. And I'm also not pretending it is an elaborate UDF. Just small and simple to use... Version 2025-01-03 * changed how temporary files are deleted * changed location of temporary files to use standard folder * added support to unusual location of AutoIt Version 2025-01-02 * corrected bug when temporary files has space within their name. Version 2024-03-24 * corrected bug when 8 parameters (max) is passed to the function Example : #AutoIt3Wrapper_Res_SaveSource=y #include "PMT-UDF.AU3" #include <Constants.au3> _PMT_Init() Local $hProc1 = _PMT_Start("Test1", Default, "Test 1") _PMT_Start("Test2") _PMT_Start("Test3", 5) Local $sResponse While Sleep(50) $sResponse = _PMT_GetResponse($hProc1) If @error Then Exit MsgBox($MB_OK, "Error", "Process has dropped") If $sResponse <> "" Then MsgBox($MB_OK, "Success", $sResponse & @CRLF) ExitLoop EndIf WEnd Func Test1($sTitle, $sMessage) Local $iResp = MsgBox($MB_OK, $sTitle, $sMessage) Return "Done with value " & $iResp EndFunc Func Test2() MsgBox($MB_OK, "2", "Test 2") EndFunc Func Test3($iTimeout) MsgBox($MB_OK, "3", "Test 3", $iTimeout) EndFunc You can pass up to 8 parameters to _PMT_Start. It is up to you to manage the right number. You cannot pass structures, maps or arrays as parameter (only bool, ptr, hWnd, int, float, string, and the keyword Default). You could use my WCD-IPC if need be to exchange large amount of data. If you want to run it compiled, you need to have add #AutoIt3Wrapper_Res_SaveSource=y at the start of your script. In the case you decide to compile your script, _PMT_Init allows you to identity where AutoIt3 is located (in the situation where AutoIt is not installed in the usual directory) to get the right includes in your "threads". Let me know if you have any question, or suggestion, I will be glad to hear them. Enjoy. PMT-UDF.au31 point
-
AutoIt Snippets
ioa747 reacted to argumentum for a topic
#include-once ;~ #include <AutoItConstants.au3> ; needed For $STDERR_CHILD & $STDOUT_CHILD Global $__g_RunWaitEx_sWorkingDir = @TempDir Global $__g_RunWaitEx_iShowFlag = @SW_HIDE Global $__g_RunWaitEx_iOptFlag = 6 ; ; "BitOR($STDERR_CHILD, $STDOUT_CHILD) = 6" Global $__g_RunWaitEx_msTimeout = 0 ; these helper functions return the set values, or sets the values if provided with one. Func _RunWaitEx_WorkingDir($val = Default) If $val <> Default Then $__g_RunWaitEx_sWorkingDir = String($val) Return $__g_RunWaitEx_sWorkingDir EndFunc ;==>_RunWaitEx_WorkingDir Func _RunWaitEx_ShowFlag($val = Default) If $val <> Default Then $__g_RunWaitEx_iShowFlag = Int($val) Return $__g_RunWaitEx_iShowFlag EndFunc ;==>_RunWaitEx_ShowFlag Func _RunWaitEx_OptFlag($val = Default) If $val <> Default Then $__g_RunWaitEx_iOptFlag = Int($val) Return $__g_RunWaitEx_iOptFlag EndFunc ;==>_RunWaitEx_ShowFlag Func _RunWaitEx_Timeout($val = Default) If $val <> Default Then $__g_RunWaitEx_msTimeout = Int($val) Return $__g_RunWaitEx_msTimeout EndFunc ;==>_RunWaitEx_Timeout ; ..say you'd like to change a default due to circumstance ;~ If Not @Compiled Then _RunWaitEx_ShowFlag(@SW_SHOW) ; this example is to showcase the errorlevel/exitcode as the @extended value. Exit ConsoleWrite('--- Text >' & _RunWaitEx("dir /.ThisWillFail") & _ '--- @error >' & @error & @CRLF & _ ; timeout ? '--- exitcode >' & @extended & @CRLF) ;RunWait: Runs an external program and pauses the script execution until the program finishes, returning the exit code of the program that was run. ;_RunWaitEx: Same as RunWait() but also returns the output text and has an optional timeout. Func _RunWaitEx($sCommand, $sWorkingDir = Default, $iShowFlag = Default, $iOptFlag = Default, $msTimeout = Default) ; https://www.autoitscript.com/forum/index.php?showtopic=139260&view=findpost&p=1478119 ; ------------------- GetExitCodeProcess portion Switch $sWorkingDir Case "/OpenProcess" Local $hPID_HANDLE = DllCall('kernel32.dll', 'ptr', 'OpenProcess', 'int', 0x400, 'int', 0, 'int', $sCommand) If Not @error Then Return $hPID_HANDLE Return SetError(1, 0, 0) Case "/GetExitCodeProcess" Local $v_Placeholder, $aRet = DllCall('kernel32.dll', 'ptr', 'GetExitCodeProcess', 'ptr', $sCommand[0], 'int*', $v_Placeholder) If Not @error And UBound($aRet) > 2 Then Return $aRet[2] Return SetError(1, 0, 0) Case "/CloseHandle" DllCall('kernel32.dll', 'ptr', 'CloseHandle', 'ptr', $sCommand) If Not @error Then Return 1 Return 0 EndSwitch ; ------------------- set defaults If $sWorkingDir = Default Then $sWorkingDir = _RunWaitEx_WorkingDir() ; @TempDir If $iShowFlag = Default Then $iShowFlag = _RunWaitEx_ShowFlag() ; @SW_HIDE If $iOptFlag = Default Then $iOptFlag = _RunWaitEx_OptFlag() ; "BitOR($STDERR_CHILD, $STDOUT_CHILD) = 6" If $msTimeout = Default Then $msTimeout = _RunWaitEx_Timeout() ; ( 0 ms. = OFF ) in case the process takes longer than expected ; ------------------- Run() Local $iPID = Run(@ComSpec & " /c " & $sCommand, $sWorkingDir, $iShowFlag, $iOptFlag) If @error Or $iPID = 0 Then Return SetError(@error + 100, 0, "") Local $iExitCode = 0, $hPID_HANDLE = _RunWaitEx($iPID, "/OpenProcess") Local $hTimer = TimerInit(), $sOutput = "" While 1 $sOutput &= StdoutRead($iPID) If @error Then ExitLoop If $msTimeout And TimerDiff($hTimer) > $msTimeout Then ExitLoop Sleep(1) WEnd While 1 $sOutput &= StderrRead($iPID) If @error Then ExitLoop If $msTimeout And TimerDiff($hTimer) > $msTimeout Then ExitLoop Sleep(1) WEnd If $hPID_HANDLE <> 0 Then $iExitCode = _RunWaitEx($hPID_HANDLE, "/GetExitCodeProcess") If $iExitCode = 259 Then $iExitCode = 100000 + $iPID ; ...process not done, should not close handle. Else ; ...the PID will be the @extended - 100000 _RunWaitEx($hPID_HANDLE, "/CloseHandle") EndIf EndIf Return SetError($msTimeout And TimerDiff($hTimer) > $msTimeout ? 200 : 0, $iExitCode, $sOutput) EndFunc ;==>_RunWaitEx I bet there are examples of this but I liked this "All In One". 2021.04.03: Added helper functions to Set or Get default values. 2021.06.25: Added OptFlag() to set/change default ( does script break from prior version )1 point -
Autoit sometimes freezes when polling StdOutRead
argumentum reacted to Dan_555 for a topic
I'v made few tests with the code. The code from the first post is freezing somewhere in between 45 and 200 rounds. I'v tested the example code from TheXman, and i stopped it after around 700 rounds, because it did not freezed. (i changed the for loop into a while loop ) Then i took the code from the 1st post and experimented a bit with it. As you can see, i tried few things: (some things are in other posts too) #include <GuiEdit.au3> #include <GuiConstantsEx.au3> #include <WindowsConstants.au3> Global $hGUI = GUICreate("CMD", 500, 400, -1, -1, BitOR($GUI_SS_DEFAULT_GUI, $WS_SIZEBOX, $WS_THICKFRAME), BitOR($WS_EX_ACCEPTFILES, $WS_EX_WINDOWEDGE)) Global $g_idMemo = GUICtrlCreateEdit("", 0, 31, 499, 349) GUISetState(@SW_SHOW) Local $i=0,$j=0, $k=0 While True $k=0 $j=$j+1 $pid = Run('tasklist.exe', @ScriptDir, @SW_HIDE, $STDOUT_CHILD) sleep (200) $sOutput = "" ;If ProcessExists($pid) Then $i=$i+1 WinSetTitle ($hGUI,"",$i & "/" & $j & "/" & $pid) Do $k=$k+1 $sOutput &= StdoutRead($pid) ; collect new output if $k>540000 then ConsoleWrite ("emergency exit" & @CRLF) ExitLoop EndIf Until @error ; EOF reached ;StdioClose($pid) ; ... you can leave them out ;ProcessWaitClose($pid) ; These two don't make a difference... MemoWrite("",1) MemoWrite($sOutput) ;EndIf Sleep(50) WEnd Func MemoWrite($sMessage = "", $clr = 0) Local $CRLF = "" If $clr = 1 Then GUICtrlSetData($g_idMemo, "") Else $CRLF = @CRLF EndIf GUICtrlSetData($g_idMemo, $sMessage & $CRLF, 0) EndFunc ;==>MemoWrite P.S. i'v added a gui and an edit field, where the output is written. This code is running, at the moment of writing, with 1500 loops without freezing. The important part here is the Sleep (200) just after the Run('tasklist.exe") line (edit #5: i'v just tried out to increase the sleep(50) and the freezing have started (not using the sleep (200) line), so it is not up to this) If you lower it, the freezing may start happening - the lower the number - the sooner the freezes. The emergency exit has not been reached in the normal run, but only with the lowered sleep amount. If a freeze (and it is not the script which is freezing, just the capturing of the output with the StdOutRead) and this, @DanP2, has allready mentioned: All consecutive run calls will fail to capture the output. Why is this happening - IDK, maybe a bug, but the question is, is it a bug in autoIt or an windows bug ... (currently the loop has reached 4200 (after few edits) as it is running in the background). Maybe someone wants to open a ticket in the bugtracker, so that the developers may look into it (if it is a bug at all) ?1 point