argumentum Posted January 18 Posted January 18 (edited) ,,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 😇 ) Spoiler expandcollapse popup#include-once ; #include <_RunWaitEx.au3> #AutoIt3Wrapper_AU3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #include <GuiEdit.au3> ;~ #include <WinAPISysWin.au3> ;~ #include <AutoItConstants.au3> ; needed For $STDERR_CHILD & $STDOUT_CHILD Global $__g_RunWaitEx_Version = 20250119 ; https://www.autoitscript.com/forum/topic/212643-_runwaitex-udf/ Global $__g_RunWaitEx_DefaultQueueMax = -1 Global $__g_RunWaitEx_LoopFunc = 0 Global $__g_RunWaitEx_LoopFuncDo = 0 Global $__g_RunWaitEx_ProcessClose = 0 Global $__g_RunWaitEx_Default_sWorkingDir = @TempDir Global $__g_RunWaitEx_Default_iShowFlag = @SW_HIDE Global $__g_RunWaitEx_Default_iOptFlag = 8 ; 6 ; "BitOR($STDERR_CHILD, $STDOUT_CHILD) = 6" Global $__g_RunWaitEx_Default_msTimeout = 0 Global $__g_RunWaitEx_Default_iCtrlEdit = 0 ; for GUICtrlCreateEdit() Global $__g_RunWaitEx_Last_sStderr = "", $__g_RunWaitEx_Last_sStdout = "", $__g_RunWaitEx_Last_iPID = 0 Global $__g_RunWaitEx_Last_iError = 0, $__g_RunWaitEx_Last_iExtended = 0, $__g_RunWaitEx_Last_hPID = 0 Global $__g_RunWaitEx_Default_iConsoleWrite = Int(Not @Compiled) ; these helper functions return the set values, or sets the values if provided with one. Func _RunWaitEx_Version() Return $__g_RunWaitEx_Version EndFunc ;==>_RunWaitEx_Version Func _RunWaitEx_ProcessClose($iVal = Default) Local $iError = 0 If $iVal <> Default Then ; note to self: do this type of checking everywhere If IsInt($iVal) Then $__g_RunWaitEx_ProcessClose = $iVal Else $iError = 1 EndIf EndIf Return SetError($iError, 0, $__g_RunWaitEx_ProcessClose) EndFunc ;==>_RunWaitEx_ProcessClose Func _RunWaitEx_DefaultQueueMax($iVal = Default) If $iVal <> Default Then $__g_RunWaitEx_DefaultQueueMax = $iVal Return $__g_RunWaitEx_DefaultQueueMax EndFunc ;==>_RunWaitEx_DefaultQueueMax Func _RunWaitEx_DefaultLoopFunc($func = Default) If IsFunc($func) Then $__g_RunWaitEx_LoopFunc = $func $__g_RunWaitEx_LoopFuncDo = 1 Else If $func <> Default Then $__g_RunWaitEx_LoopFunc = "" $__g_RunWaitEx_LoopFuncDo = 0 EndIf EndIf Return SetError(0, IsFunc($__g_RunWaitEx_LoopFunc), FuncName($__g_RunWaitEx_LoopFunc)) EndFunc ;==>_RunWaitEx_DefaultLoopFunc Func _RunWaitEx_DefaultWorkingDir($sVal = Default) If $sVal <> Default Then $__g_RunWaitEx_Default_sWorkingDir = String($sVal) Return $__g_RunWaitEx_Default_sWorkingDir EndFunc ;==>_RunWaitEx_DefaultWorkingDir Func _RunWaitEx_DefaultShowFlag($iVal = Default) If $iVal <> Default Then $__g_RunWaitEx_Default_iShowFlag = Int($iVal) Return $__g_RunWaitEx_Default_iShowFlag EndFunc ;==>_RunWaitEx_DefaultShowFlag Func _RunWaitEx_DefaultOptFlag($val = Default) If $val <> Default Then $__g_RunWaitEx_Default_iOptFlag = Int($val) Return $__g_RunWaitEx_Default_iOptFlag EndFunc ;==>_RunWaitEx_DefaultOptFlag Func _RunWaitEx_DefaultTimeout($val = Default) If $val <> Default Then $__g_RunWaitEx_Default_msTimeout = Int($val) Return $__g_RunWaitEx_Default_msTimeout EndFunc ;==>_RunWaitEx_DefaultTimeout Func _RunWaitEx_DefaultCtrlEdit($CtrlId = Default) ; v20250119 Local $iError = 0 If $CtrlId <> Default Then If __RunWaitEx_WinAPI_GetClassName($CtrlId) = "Edit" Then $__g_RunWaitEx_Default_iCtrlEdit = Int($CtrlId) Else $iError = 1 EndIf EndIf Return SetError($iError, 0, $__g_RunWaitEx_Default_iCtrlEdit) EndFunc ;==>_RunWaitEx_DefaultCtrlEdit Func _RunWaitEx_DefaultConsoleWrite($val = Default) If $val <> Default Then $__g_RunWaitEx_Default_iConsoleWrite = Int($val) Return $__g_RunWaitEx_Default_iConsoleWrite EndFunc ;==>_RunWaitEx_DefaultConsoleWrite Func _RunWaitEx_Last_iPID() Return $__g_RunWaitEx_Last_iPID EndFunc ;==>_RunWaitEx_Last_iPID Func _RunWaitEx_Last_hPID() Return $__g_RunWaitEx_Last_hPID EndFunc ;==>_RunWaitEx_Last_hPID Func _RunWaitEx_LastStdout($val = Default) If $val <> Default Then $__g_RunWaitEx_Last_sStdout = $val Return $__g_RunWaitEx_Last_sStdout EndFunc ;==>_RunWaitEx_LastStdout Func _RunWaitEx_LastStderr($val = Default) If $val <> Default Then $__g_RunWaitEx_Last_sStderr = $val Return $__g_RunWaitEx_Last_sStderr EndFunc ;==>_RunWaitEx_LastStderr Func _RunWaitEx_LastError() Return $__g_RunWaitEx_Last_iError EndFunc ;==>_RunWaitEx_LastError Func _RunWaitEx_LastExtended() Return $__g_RunWaitEx_Last_iExtended EndFunc ;==>_RunWaitEx_LastExtended ; ..say you'd like to change a default due to circumstance ;~ If Not @Compiled Then _RunWaitEx_DefaultShowFlag(@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) ; the ErrorLevel returned by the executable ;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, $iCtrlEdit = Default) ; https://www.autoitscript.com/forum/index.php?showtopic=139260&view=findpost&p=1478119 ; ------------------- GetExitCodeProcess portion Local $hPID_HANDLE, $iExitCode = 0 Switch $sWorkingDir Case "/OpenProcess" $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 ; ------------------- get defaults If $sWorkingDir = Default Then $sWorkingDir = _RunWaitEx_DefaultWorkingDir() ; @TempDir If $iShowFlag = Default Then $iShowFlag = _RunWaitEx_DefaultShowFlag() ; @SW_HIDE If $iOptFlag = Default Then $iOptFlag = _RunWaitEx_DefaultOptFlag() ; "BitOR($STDERR_CHILD, $STDOUT_CHILD) = 6" If $msTimeout = Default Then $msTimeout = _RunWaitEx_DefaultTimeout() ; ( 0 ms. = OFF ) in case the process takes longer than expected If $iCtrlEdit = Default Then $iCtrlEdit = _RunWaitEx_DefaultCtrlEdit() ; in case a "Console" is needed ; ------------------- Run() If Not StringInStr($sCommand, @ComSpec) = 1 Then $sCommand = @ComSpec & " /c " & $sCommand Local $iPID = Run($sCommand, $sWorkingDir, $iShowFlag, $iOptFlag) If @error Or $iPID = 0 Then Return SetError(@error + 100, 0, "") $hPID_HANDLE = _RunWaitEx($iPID, "/OpenProcess") $__g_RunWaitEx_Last_iPID = $iPID $__g_RunWaitEx_Last_hPID = $hPID_HANDLE Local $sStr, $hTimer = TimerInit() $__g_RunWaitEx_Last_sStdout = "" $__g_RunWaitEx_Last_sStderr = "" $__g_RunWaitEx_Last_iError = String("") $__g_RunWaitEx_Last_iExtended = String("") While 1 $sStr = StdoutRead($iPID) If @error Then ExitLoop If $msTimeout And TimerDiff($hTimer) > $msTimeout Then ExitLoop If $__g_RunWaitEx_Default_iConsoleWrite Then ConsoleWrite($sStr) If $iCtrlEdit And $sStr <> "" Then _GUICtrlEdit_AppendText($iCtrlEdit, StringReplace($sStr, @CR, @CRLF) & @CRLF) $__g_RunWaitEx_Last_sStdout &= $sStr If $__g_RunWaitEx_LoopFuncDo Then $__g_RunWaitEx_LoopFunc($sStr, "") If $__g_RunWaitEx_ProcessClose Then ExitLoop If $__g_RunWaitEx_DefaultQueueMax > -1 Then $__g_RunWaitEx_Last_sStdout = StringRight($__g_RunWaitEx_Last_sStdout, $__g_RunWaitEx_DefaultQueueMax) Sleep(1) WEnd While 1 $sStr = StderrRead($iPID) If @error Then ExitLoop If $msTimeout And TimerDiff($hTimer) > $msTimeout Then ExitLoop If $__g_RunWaitEx_Default_iConsoleWrite Then ConsoleWrite($sStr) If $iCtrlEdit And $sStr <> "" Then _GUICtrlEdit_AppendText($iCtrlEdit, StringReplace($sStr, @CR, @CRLF) & @CRLF) $__g_RunWaitEx_Last_sStderr &= $sStr If $__g_RunWaitEx_LoopFuncDo Then $__g_RunWaitEx_LoopFunc("", $sStr) If $__g_RunWaitEx_ProcessClose Then ExitLoop If $__g_RunWaitEx_DefaultQueueMax > -1 Then $__g_RunWaitEx_Last_sStderr = StringRight($__g_RunWaitEx_Last_sStderr, $__g_RunWaitEx_DefaultQueueMax) Sleep(1) WEnd If $__g_RunWaitEx_ProcessClose Then ProcessClose($iPID) 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 $__g_RunWaitEx_ProcessClose = 0 $__g_RunWaitEx_Last_iError = ($msTimeout And TimerDiff($hTimer) > $msTimeout ? 200 : 0) $__g_RunWaitEx_Last_iExtended = $iExitCode _RunWaitEx_ProcessClose(0) ; just in case the user didn't. Return SetError($__g_RunWaitEx_Last_iError, $iExitCode, $__g_RunWaitEx_Last_sStdout & $__g_RunWaitEx_Last_sStderr) EndFunc ;==>_RunWaitEx Func __RunWaitEx_WinAPI_GetClassName($hWnd) ; from <WinAPISysWin.au3> ; internal use If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd) Local $aCall = DllCall("user32.dll", "int", "GetClassNameW", "hwnd", $hWnd, "wstr", "", "int", 4096) If @error Or Not $aCall[0] Then Return SetError(@error, @extended, '') Return SetExtended($aCall[0], $aCall[2]) EndFunc ;==>__RunWaitEx_WinAPI_GetClassName   and here is the demo code expandcollapse popup#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 ). Edited January 18 by argumentum updated to 20250119 ioa747, mLipok and SOLVE-SMART 2 1 Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
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