Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

StdIn()


  • Please log in to reply
7 replies to this topic
Lexikos
  • Administrators
  • 9592 posts
  • Last active: Today, 12:17 AM
  • Joined: 17 Oct 2006
StdIn(max_chars = 0xfff)
Reads up to max_chars bytes from the script's standard input handle.
StdIn(max_chars=0xfff)
{
    static hStdIn=-1

    if (hStdIn = -1)
    {
        hStdIn := DllCall("GetStdHandle", "UInt", -10) ; -10=STD_INPUT_HANDLE
        if ErrorLevel
            return 0
    }

    max_chars := VarSetCapacity(text, max_chars, 0)

    ret := DllCall("ReadFile"
        , "UInt", hStdIn        ; hFile
        ,  "Str", text          ; lpBuffer
        , "UInt", max_chars     ; nNumberOfBytesToRead
        , "UIntP", bytesRead    ; lpNumberOfBytesRead
        , "UInt", 0)            ; lpOverlapped

    return text
}
Not tested for Unicode compatibility. Requested by tinku99 here.

fincs
  • Moderators
  • 1662 posts
  • Last active:
  • Joined: 05 May 2007
Here you go:
StdIn(max_chars=0xfff)
{
    static hStdIn=-1
    [color=orange]; The following is for vanilla compatibility
    ptrtype := (A_PtrSize = 8) ? "ptr" : "uint"[/color]

    if (hStdIn = -1)
    {
        hStdIn := DllCall("GetStdHandle", "UInt", -10[color=orange],  ptrtype[/color]) ; -10=STD_INPUT_HANDLE
        if ErrorLevel
            return 0
    }

    max_chars := VarSetCapacity(text, max_chars[color=orange]*(!!A_IsUnicode+1)[/color], 0)

    ret := DllCall("ReadFile"
        ,  [color=orange]ptrtype[/color], hStdIn        ; hFile
        ,  "Str", text          ; lpBuffer
        , "UInt", max_chars[color=orange]*(!!A_IsUnicode+1)[/color]     ; nNumberOfBytesToRead
        , "UInt*", bytesRead    ; lpNumberOfBytesRead
        ,  [color=orange]ptrtype[/color], 0)            ; lpOverlapped

    return text
}

Pretty easy to fix. Works (hopefully) on vanilla AutoHotkey, ANSI/Unicode AutoHotkey_L and ANSI/Unicode AutoHotkey64. That's what you call portable code ;p

tinku99
  • Members
  • 560 posts
  • Last active: Feb 08 2015 12:54 AM
  • Joined: 03 Aug 2007
thanks lexikos.

earlsd
  • Members
  • 50 posts
  • Last active: Sep 02 2011 07:24 PM
  • Joined: 13 Apr 2011
I can't seem to get this function to return more than 4107 bytes no matter what I set max_chars to. Any ideas what I'm doing wrong?

Lexikos
  • Administrators
  • 9592 posts
  • Last active: Today, 12:17 AM
  • Joined: 17 Oct 2006
If there's data available, it will return it. It won't wait until your buffer is full. If you want more data, call the function again.

earlsd
  • Members
  • 50 posts
  • Last active: Sep 02 2011 07:24 PM
  • Joined: 13 Apr 2011

If there's data available, it will return it. It won't wait until your buffer is full. If you want more data, call the function again.



FYI: I was able to loop until the function stopped returning data then break. I guess I just didn't know how to use it:

loop
{
    sleep 100 ;Seems to need to wait for data
	PipeBuffer:=StdIn()
    if PipeBuffer is space
        break
    PipeText:=PipeText . PipeBuffer
}


ObiWanKenobi
  • Members
  • 83 posts
  • Last active: Yesterday, 08:30 PM
  • Joined: 21 Aug 2012

*double post, please remove this post*



ObiWanKenobi
  • Members
  • 83 posts
  • Last active: Yesterday, 08:30 PM
  • Joined: 21 Aug 2012

Hello guys, this worked for me in AutoHotKey_L:

receiver.ahk

StdIn(piMaxChars:=4095, psEncoding:="CP0")
{
    sRetVal:=""
    static hStdIn:=-1

    if (hStdIn=-1)
    {
        hStdIn := DllCall("GetStdHandle", UInt, -10) ; -10=STD_INPUT_HANDLE
        if ErrorLevel
            return 0
    }

    VarSetCapacity(sText, piMaxChars)
    while (DllCall("ReadFile", Ptr, hStdIn, Ptr, &sText, UInt, piMaxChars, PtrP, nSize, Ptr, 0))
        sRetVal .= StrGet(&sText, nSize, psEncoding)

    return sRetVal
} 


;Read PipeText via StdIn
PipeText := ""
loop
{
    sleep 100
    PipeBuffer := StdIn()
    if PipeBuffer is space
        break
    PipeText .= PipeBuffer
}

MsgBox, % PipeText

And I sent it with:

StdoutToVar_CreateProcess(psCmd, psInput="", psEncoding:="CP0", psDir:="", ByRef pnExitCode:=0)
{
    DllCall("CreatePipe",           PtrP, hStdInRd,  PtrP, hStdInWr,  Ptr,  0, UInt, 0)
    DllCall("CreatePipe",           PtrP, hStdOutRd, PtrP, hStdOutWr, Ptr,  0, UInt, 0)
    DllCall("SetHandleInformation", Ptr, hStdInRd, Uint,  1, Uint, 1)
    DllCall("SetHandleInformation", Ptr, hStdOutWr, UInt, 1, UInt, 1)

            VarSetCapacity(pi, (A_PtrSize == 4) ? 16 : 24,  0)
    siSz := VarSetCapacity(si, (A_PtrSize == 4) ? 68 : 104, 0)
    NumPut(siSz,      si,  0,                          "UInt")
    NumPut(0x100,     si,  (A_PtrSize == 4) ? 44 : 60, "UInt")
    NumPut(hStdInRd,  si,  (A_PtrSize == 4) ? 56 : 80, "Ptr")
    NumPut(hStdOutWr, si,  (A_PtrSize == 4) ? 60 : 88, "Ptr")
    NumPut(hStdOutWr, si,  (A_PtrSize == 4) ? 64 : 96, "Ptr")

    If (!DllCall("CreateProcess", Ptr,0, Ptr, &psCmd, Ptr, 0, Ptr, 0, Int, True, UInt, 0x08000000
                                , Ptr, 0, Ptr, psDir ? &psDir : 0, Ptr, &si, Ptr, &pi))
        return
      , DllCall("CloseHandle", Ptr,hStdOutWr)
      , DllCall("CloseHandle", Ptr,hStdOutRd)
      , DllCall("CloseHandle", Ptr,hStdInRd)

    DllCall("CloseHandle", Ptr,hStdOutWr ) ; The write pipe must be closed before reading the stdout.
    
    if (psInput != "")
        FileOpen(hStdInWr, "h", psEncoding).Write(psInput)
	DllCall("CloseHandle", "Ptr", hStdInWr)
    
    VarSetCapacity(sTemp, 4095)
    while (DllCall("ReadFile", Ptr, hStdOutRd, Ptr, &sTemp, UInt, 4095, PtrP, nSize, Ptr, 0))
        sOutput .= StrGet(&sTemp, nSize, psEncoding)

    DllCall("GetExitCodeProcess", Ptr, NumGet(pi,0), UIntP, pnExitCode)
    DllCall("CloseHandle",        Ptr, NumGet(pi,0)                   )
    DllCall("CloseHandle",        Ptr, NumGet(pi,A_PtrSize)           )
    DllCall("CloseHandle",        Ptr, hStdOutRd                      )
    return sOutput
}

... like this:

 

sender.ahk

sText := "Hello World!`nHello World!`nHello World!`nHello World!`nHello World!`nHello World!`nHello World!`nHello World!`nHello World!`nHello World!`nHello World!`nHello World!`nHello World!`nHello World!`nHello World!`nHello World!`nHello World!`nHello World!`nHello World!`nHello World!`n"

sAHKInterpreter := "C:\Program Files\AutoHotkey\AutoHotkey.exe"
sAHKScript := "C:\Scripts\test\receiver.ahk"
sArguments:=""
sCommand = "%sAHKInterpreter%" "%sAHKScript%" %sArguments%
sResult := StdoutToVar_CreateProcess(sCommand, sText)

Everything fine, even with German Umlauts etc.