Jump to content

StdoutRead freezes


VAN0
 Share

Go to solution Solved by Nine,

Recommended Posts

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 by VAN0
Link to comment
Share on other sites

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

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 parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 22/04/2018

Link to comment
Share on other sites

  • 11 months later...

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

  • 10 years later...

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

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 by AndrewG
Link to comment
Share on other sites

  • Solution

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 by Nine
Link to comment
Share on other sites

@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

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.

Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...