VAN0 Posted February 10, 2013 Share Posted February 10, 2013 (edited) Hello. I've tried search the forum and found few topic with the same issues, but none of them have working solution for me. I have the following code: Local $line = "" Local $foo = Run(@ComSpec & " /c powercfg -list", @SystemDir, @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD) While 1 $line &= StdoutRead($foo) If @error Then ExitLoop WEnd If I put this in a loop, after a while it freezes in the infinite loop because StdoutRead doesn't through @error I'm not quiet understand how this piece of code actually works and the only workaround solution I can think of is instead of creating infinite loop, use counter to let say 10000 loops, but this will fail on super fast computers I guess: $i = 10000 Local $line = "" Local $foo = Run(@ComSpec & " /c powercfg -list", @SystemDir, @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD) Do $line &= StdoutRead($foo) If @error Then ExitLoop $p = ProcessExists($foo) If Not $p Then $i -= 1 Until Not $i The second code works for me so far, but is there a "proper" way handle this issue when StdoutRead indefinitely waiting for output? Thank you. P.S. suggested using sleep() would affect on script performance, so I'd rather avoid it too. Edited February 10, 2013 by VAN0 Link to comment Share on other sites More sharing options...
JohnOne Posted February 10, 2013 Share Posted February 10, 2013 Not quite an expert on this but does the window close after operation? If so While ProcessExists($foo) $line &= StdoutRead($foo) If @error Then ExitLoop WEnd or While ProcessExists($foo) Sleep(10) WEnd $line = StdoutRead($foo) AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
guinness Posted February 10, 2013 Share Posted February 10, 2013 Here's how I would do it. ; Example 1 Local $sOutput = '' While 1 $sOutput &= StdoutRead($iPID) ; Read the standard output stream. If @error Then ; This will exit the loop if the process doesn't exists. ExitLoop EndIf WEnd ; Example 2 ProcessWaitClose($iPID) ; Wait for the process to close. Local $sOutput = StdoutRead($iPID) ; Read the standard output stream. UDF List: _AdapterConnections() • _AlwaysRun() • _AppMon() • _AppMonEx() • _ArrayFilter/_ArrayReduce • _BinaryBin() • _CheckMsgBox() • _CmdLineRaw() • _ContextMenu() • _ConvertLHWebColor()/_ConvertSHWebColor() • _DesktopDimensions() • _DisplayPassword() • _DotNet_Load()/_DotNet_Unload() • _Fibonacci() • _FileCompare() • _FileCompareContents() • _FileNameByHandle() • _FilePrefix/SRE() • _FindInFile() • _GetBackgroundColor()/_SetBackgroundColor() • _GetConrolID() • _GetCtrlClass() • _GetDirectoryFormat() • _GetDriveMediaType() • _GetFilename()/_GetFilenameExt() • _GetHardwareID() • _GetIP() • _GetIP_Country() • _GetOSLanguage() • _GetSavedSource() • _GetStringSize() • _GetSystemPaths() • _GetURLImage() • _GIFImage() • _GoogleWeather() • _GUICtrlCreateGroup() • _GUICtrlListBox_CreateArray() • _GUICtrlListView_CreateArray() • _GUICtrlListView_SaveCSV() • _GUICtrlListView_SaveHTML() • _GUICtrlListView_SaveTxt() • _GUICtrlListView_SaveXML() • _GUICtrlMenu_Recent() • _GUICtrlMenu_SetItemImage() • _GUICtrlTreeView_CreateArray() • _GUIDisable() • _GUIImageList_SetIconFromHandle() • _GUIRegisterMsg() • _GUISetIcon() • _Icon_Clear()/_Icon_Set() • _IdleTime() • _InetGet() • _InetGetGUI() • _InetGetProgress() • _IPDetails() • _IsFileOlder() • _IsGUID() • _IsHex() • _IsPalindrome() • _IsRegKey() • _IsStringRegExp() • _IsSystemDrive() • _IsUPX() • _IsValidType() • _IsWebColor() • _Language() • _Log() • _MicrosoftInternetConnectivity() • _MSDNDataType() • _PathFull/GetRelative/Split() • _PathSplitEx() • _PrintFromArray() • _ProgressSetMarquee() • _ReDim() • _RockPaperScissors()/_RockPaperScissorsLizardSpock() • _ScrollingCredits • _SelfDelete() • _SelfRename() • _SelfUpdate() • _SendTo() • _ShellAll() • _ShellFile() • _ShellFolder() • _SingletonHWID() • _SingletonPID() • _Startup() • _StringCompact() • _StringIsValid() • _StringRegExpMetaCharacters() • _StringReplaceWholeWord() • _StringStripChars() • _Temperature() • _TrialPeriod() • _UKToUSDate()/_USToUKDate() • _WinAPI_Create_CTL_CODE() • _WinAPI_CreateGUID() • _WMIDateStringToDate()/_DateToWMIDateString() • Au3 script parsing • AutoIt Search • AutoIt3 Portable • AutoIt3WrapperToPragma • AutoItWinGetTitle()/AutoItWinSetTitle() • Coding • DirToHTML5 • FileInstallr • FileReadLastChars() • GeoIP database • GUI - Only Close Button • GUI Examples • GUICtrlDeleteImage() • GUICtrlGetBkColor() • GUICtrlGetStyle() • GUIEvents • GUIGetBkColor() • Int_Parse() & Int_TryParse() • IsISBN() • LockFile() • Mapping CtrlIDs • OOP in AutoIt • ParseHeadersToSciTE() • PasswordValid • PasteBin • Posts Per Day • PreExpand • Protect Globals • Queue() • Resource Update • ResourcesEx • SciTE Jump • Settings INI • SHELLHOOK • Shunting-Yard • Signature Creator • Stack() • Stopwatch() • StringAddLF()/StringStripLF() • StringEOLToCRLF() • VSCROLL • WM_COPYDATA • More Examples... Updated: 22/04/2018 Link to comment Share on other sites More sharing options...
garbb Posted January 28, 2014 Share Posted January 28, 2014 I had the same problem of stdoutread() hanging up intermittently in my script. I made it run in a loop and usually it would only run a few hundred times before stdoutread() would freeze. This is the best I could come up with: Local $foo = Run(@ComSpec & " /c dir foo.bar", "C:\", @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD + $RUN_CREATE_NEW_CONSOLE) Do until NOT ProcessExists($foo) Local $line = StdoutRead($foo) StdioClose($foo) ConsoleWrite("STDOUT read:"&' "'&$line&'"'&@CR) It seems to run forever without freezing. For some reason if you use "ProcessWaitClose($foo)" it will make the script much slower that if you use "Do until NOT ProcessExists($foo)" even though I would think that they are doing the exact same thing. Also don't forget to use StdioClose($foo) or you will probably have a memory leak. (I definitely did) I know that this is an old thread but I happened across it when searching for a solution to my problem and so hopefully someone else will in the future. Link to comment Share on other sites More sharing options...
VAN0 Posted September 15 Author Share Posted September 15 9 years later this topic is still relevant. using ProcessWaitClose() as per help file absolutely murders performance of the script (it's 1:10 ratio difference) But with ProcessExists() performance slightly drops, but no freezes. So, my current working work around: Local $line = "" Local $foo = Run(@ComSpec & " /c powercfg -list", @SystemDir, @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD) While 1 $line &= StdoutRead($foo) If @error Or Not ProcessExists($iPID) Then ExitLoop WEnd $line &= StdoutRead($foo) P.S. If I remove the last line, for some reason sometimes I get no data read at all ... Link to comment Share on other sites More sharing options...
AndrewG Posted September 15 Share Posted September 15 (edited) It's easier to get the output after the command finishes. https://www.autoitscript.com/forum/topic/203959-autoit-sometimes-freezes-when-polling-stdoutread/?do=findComment&comment=1464904 You stated that you have tried ProcessWaitClose(), but not shown is where you placed ProcessWaitClose() in your example. I could assume where, but that is not wise. So... The following works for me; returns quickly, does not freeze. Does this work for you? #Include <AutoItConstants.au3> Local $line = "" Local $foo = Run(@ComSpec & " /c powercfg -list", @SystemDir, @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD) While 1 $line &= StdoutRead($foo) If @error Then ExitLoop ProcessWaitClose($foo) WEnd ConsoleWrite($line & @CRLF) Edited September 15 by AndrewG Link to comment Share on other sites More sharing options...
Solution Nine Posted September 15 Solution Share Posted September 15 (edited) As per help file of ProcessWaitClose : Quote The process is polled approximately every 250 milliseconds. If 250 ms is too long for you then simply use this : #include <Constants.au3> Local $hTimer = TimerInit() Local $iPID = Run(@ComSpec & " /c powercfg -list", "", @SW_HIDE, $STDERR_MERGED) While ProcessExists($iPID) WEnd Local $line = StdoutRead($iPID) ConsoleWrite(TimerDiff($hTimer) & @CRLF) ConsoleWrite($line & @CRLF) 42ms instead of 295ms with ProcessWaitClose Edited September 15 by Nine AndrewG and VAN0 1 1 “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
VAN0 Posted September 19 Author Share Posted September 19 @Nine That actually even better. Thank you! So, how does the sdout buffer work? Does it remains in memory until it's read even after application process is gone? What if it's megabytes or even gigabytes of data? Link to comment Share on other sites More sharing options...
Nine Posted September 19 Share Posted September 19 I don't think it is allowed to write to console more than 64k, although I haven't check recently on new OS. Anyway this rhetorical question, you can try by yourself. “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy 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