Buchempfehlung
Mikrocomputertechnik mit Controllern der Atmel AVR-RISC-Familie
Mikrocomputertechnik mit Controllern der Atmel AVR-RISC-Familie
Umfassend, aber leicht verständlich führt dieses Buch in die Programmierung von ATMEL AVR Mikrocontrollern ein. [Mehr Infos...]
FreeBASIC-Chat
Es sind Benutzer im FreeBASIC-Chat online.
(Stand:  )
FreeBASIC bei Twitter
Twitter FreeBASIC-Nachrichten jetzt auch über Twitter erhalten. Follow us!

Code-Beispiel

Code-Beispiele » Kleine Helferlein

bipipe.bi

Lizenz:Erster Autor:Letzte Bearbeitung:
WTFPLMitgliedgrindstone 05.03.2020

Die hier vorgestellte Bibliothek stellt - per #Include eingebunden - 5 Funktionen zur Verfügung:

English

(translated by Externer Link!chris319)

The library presented here provides 5 functions - integrated via #Include:

1. bipOpen (ProgrammName, [showmode]) - Opens the (console) program ProgrammName and sets up two unidirectional pipes for communication. The optional parameter showmode defines the appearance of the called program. For possible parameters see https://docs.microsoft.com/en-us/window ... dfrom=MSDN. The default is SW_NORMAL. The return value is a pointer to the corresponding HANDLE array (HandlePointer).

2. bipClose (HandlePointer) - Ends the program, closes the pipes, clears the handles, releases the memory and sets the HandlePointer to 0.

3. bipWrite (HandlePointer, text, ["b"]) - Sends a string for standard input of the opened program. If the optional parameter "b" (for binary) is set, the string is sent unchanged, otherwise a Chr (13,10) is added.

4. bipRead (HandlePointer, [timeout]) - Reads the standard output of the program. The default for timeout is 100ms.

5. bipReadLine (HandlePointer, [separator], [timeout]) - Reads a line from the started program, analogous to the "Line Input" command. The optional separator parameter is either an "a" (for any) followed by a list of characters, each of which ends the line, or an "e" (for exact), followed by one or more characters to represent the separator , The default is "a" & Chr (13,10). The default for timeout is 100ms.

#Include Once "windows.bi"

Type bipdata
    hProcessHandle As HANDLE
    hWritePipe As HANDLE
    hReadPipe As HANDLE
End Type

Function bipOpen(PrgName As String, showmode As Short = SW_NORMAL) As bipdata Ptr

    Dim As STARTUPINFO si
    Dim As PROCESS_INFORMATION pi
    Dim As SECURITY_ATTRIBUTES sa
    Dim As HANDLE hReadPipe, hWritePipe, hReadChildPipe, hWriteChildPipe
    Dim pPipeHandles As bipdata Ptr

    'set security attributes
    sa.nLength = SizeOf(SECURITY_ATTRIBUTES)
    sa.lpSecurityDescriptor = NULL 'use default descriptor
    sa.bInheritHandle = TRUE

    'create one pipe for each direction
    CreatePipe(@hReadChildPipe,@hWritePipe,@sa,0) 'parent to child
    CreatePipe(@hReadPipe,@hWriteChildPipe,@sa,0) 'child to parent

    GetStartupInfo(@si)

    si.dwFlags = STARTF_USESTDHANDLES Or STARTF_USESHOWWINDOW
    si.wShowWindow = showmode 'appearance of child process window
    si.hStdOutput  = hWriteChildPipe
    si.hStdError   = hWriteChildPipe
    si.hStdInput   = hReadChildPipe

    CreateProcess(0,PrgName,0,0,TRUE,CREATE_NEW_CONSOLE,0,0,@si,@pi)

    CloseHandle(hWriteChildPipe)
    CloseHandle(hReadChildPipe)

    pPipeHandles = Allocate (SizeOf(bipdata)) 'area for storing the handles
    pPipeHandles->hProcessHandle = pi.hProcess 'handle to child process
    pPipeHandles->hWritePipe = hWritePipe
    pPipeHandles->hReadPipe = hReadPipe

    Return pPipeHandles 'pointer to handle array

End Function

Sub bipClose(ByRef pPipeHandles As bipdata Ptr)

    If pPipeHandles = 0 Then Return
    TerminateProcess(pPipeHandles->hProcessHandle, 0)
    CloseHandle(pPipeHandles->hWritePipe)
    CloseHandle(pPipeHandles->hReadPipe)
    DeAllocate(pPipeHandles)
    pPipeHandles = 0

End Sub

Function bipWrite(pPipeHandles As bipdata Ptr, text As String, mode As String = "") As Integer
    Dim As Integer iNumberOfBytesWritten
    'Dim As String txt = text

    '? Len(text);" ";
    If pPipeHandles = 0 Then Return 0
    If LCase(mode) <> "b" Then 'not binary mode
        text += Chr(13,10)
    EndIf

    WriteFile(pPipeHandles->hWritePipe,StrPtr(text),Len(text),@iNumberOfBytesWritten,0)
    Return iNumberOfBytesWritten

End Function


Function bipRead(pPipeHandles As bipdata Ptr, timeout As UInteger = 100) As String
    'returns the whole pipe content until the pipe is empty or timeout occurs.
    ' timeout default is 100ms to prevent a deadlock

    Dim As Integer iNumberOfBytesRead, iTotalBytesAvail, iBytesLeftThisMessage
    Dim As String buffer, retText
    Dim As Double tout = Timer + Cast(Double,timeout) / 1000

    If pPipeHandles = 0 Then Return "" 'no valid pointer

    Do
        PeekNamedPipe(pPipeHandles->hReadPipe,0,0,0,@iTotalBytesAvail,0)
        If iTotalBytesAvail Then
            buffer = String(iTotalBytesAvail,Chr(0))
            ReadFile(pPipeHandles->hReadPipe,StrPtr(buffer),Len(buffer),@iNumberOfBytesRead,0)
            retText &= buffer
        ElseIf Len(retText) Then
            Exit Do
        EndIf
    Loop Until Timer > tout

    Return retText

End Function

Function bipReadLine(pPipeHandles As bipdata Ptr, separator As String = "a" & Chr(13,10), timeout As UInteger = 100) As String
    'returns the pipe content till the first separator if any, or otherwise the whole pipe
    ' content on timeout. timeout default is 100ms to prevent a deadlock

    Dim As Integer iNumberOfBytesRead, iTotalBytesAvail, iBytesLeftThisMessage, endPtr
    Dim As String buffer, retText, mode
    Dim As Double tout = Timer + Cast(Double,timeout) / 1000

    If pPipeHandles = 0 Then Return "" 'no valid pointer

    mode = LCase(Left(separator,1))
    separator = Mid(separator,2)

    Do
        PeekNamedPipe(pPipeHandles->hReadPipe,0,0,0,@iTotalBytesAvail,0)
        If iTotalBytesAvail Then
            buffer = String(iTotalBytesAvail,Chr(0))
            PeekNamedPipe(pPipeHandles->hReadPipe,StrPtr(buffer),Len(buffer),@iNumberOfBytesRead, _
                          @iTotalBytesAvail,@iBytesLeftThisMessage) 'copy pipe content to buffer
            Select Case mode
                Case "a" 'any
                    endPtr = InStr(buffer, Any separator) 'look for line end sign
                Case "e" 'exact
                    endPtr = InStr(buffer, separator) 'look for line end sign
            End Select
            If endPtr Then 'return pipe content till line end
                Select Case mode
                    Case "a"
                        Do While (InStr(separator,Chr(buffer[endPtr - 1]))) And (endPtr < Len(buffer))
                            endPtr += 1
                        Loop
                        endPtr -= 1
                    Case "e"
                        endPtr += Len(separator)
                End Select
                retText = Left(buffer,endPtr)
                ReadFile(pPipeHandles->hReadPipe,StrPtr(buffer),endPtr,@iNumberOfBytesRead,0) 'remove read bytes from pipe
                Select Case mode
                    Case "a"
                        Return RTrim(retText,Any separator) 'remove line end sign from returned string
                    Case "e"
                        Return Left(retText,Len(retText) - Len(separator))
                End Select
            EndIf
        EndIf
    Loop Until Timer > tout

    If iTotalBytesAvail Then 'return all pipe content
        buffer = String(iTotalBytesAvail,Chr(0))
        ReadFile(pPipeHandles->hReadPipe,StrPtr(buffer),Len(buffer),@iNumberOfBytesRead,0)
        Return buffer
    EndIf

    Return ""

End Function

Zusätzliche Informationen und Funktionen
  • Das Code-Beispiel wurde am 03.06.2015 von Mitgliedgrindstone angelegt.
  • Die aktuellste Version wurde am 05.03.2020 von Mitgliedgrindstone gespeichert.
  Bearbeiten Bearbeiten  

  Versionen Versionen