B4J Question Named Pipes under Windows

MM2forever

Active Member
Licensed User
Longtime User
Hello everyone, I have tried to open a pipe under Windows and write to it.

With PipeViewer - PipeChat (https://github.com/cyberark/PipeViewer/releases/tag/v.1.1) I managed the communication with the process successfully.
How do I open a pipe in B4J? I have searched the forum and found nothing suitable, I assumed that this is handled normally as asynchronous file access but I can't reproduce my results with PipeChat.

This is my code:

B4X:
#Region Project Attributes
    #MainFormWidth: 600
    #MainFormHeight: 600
#End Region

Sub Process_Globals
    Private fx As JFX
    Private MainForm As Form
    Private xui As XUI

    Private AStreams As AsyncStreams
End Sub

Sub AppStart (Form1 As Form, Args() As String)
    MainForm = Form1
    MainForm.RootPane.LoadLayout("Layout1")
    MainForm.Show
    
    Dim input As InputStream = File.OpenInput("\\.\pipe\","HmiRuntime")
    Dim output As OutputStream = File.OpenOutput("\\.\pipe\","HmiRuntime",True)
    AStreams.Initialize(input, output, "AStreams")
    
    Dim buffer() As Byte
    buffer = ("BrowseTags * 100 --filter *"&CRLF).GetBytes("UTF8")
    AStreams.Write(buffer)
End Sub


Sub AStreams_NewData (Buffer() As Byte)
    Dim msg As String
    msg = BytesToString(Buffer, 0, Buffer.Length, "UTF8")
    Log(msg)
End Sub

Nothing crashes but also nothing really happens.

Thanks, Chris
 

Daestrum

Expert
Licensed User
Longtime User
Not tried using pipes (well I don't remember trying) but you may have to use javas PipedInputStream & PipedOutputStream using Javaobject.
 
Upvote 0

MM2forever

Active Member
Licensed User
Longtime User
PipedInputStream / PipedOutputStream are not related to OS pipes.

Based on this: https://stackoverflow.com/questions/634564/how-to-open-a-windows-named-pipe-from-java your code looks correct, but only if the pipe already exists.
Funny I just had a look at the same SO thread and came to the conclusion that it 'should work'.
Yes, the pipe exists, it is created by another piece of software I just want to talk to.

I will fiddle about and hopefully find a solution and let everyone know for future reference.
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Use these methods instead of the standard File methods:
B4X:
Private Sub OpenOutputNonBuffered (Dir As String, FileName As String, Append As Boolean) As OutputStream
    Dim f As JavaObject
    f.InitializeNewInstance("java.io.File", Array(Dir, FileName))
    Dim out As JavaObject
    out.InitializeNewInstance("java.io.FileOutputStream", Array(f, Append))
    Return out
End Sub

Private Sub OpenInputNonBuffered (Dir As String, FileName As String) As InputStream
    Dim f As JavaObject
    f.InitializeNewInstance("java.io.File", Array(Dir, FileName))
    Dim in As JavaObject
    in.InitializeNewInstance("java.io.FileInputStream", Array(f))
    Return in
End Sub

The File methods add a buffer which might be problematic in this case.
 
Upvote 0

MM2forever

Active Member
Licensed User
Longtime User
Use these methods instead of the standard File methods:
B4X:
Private Sub OpenOutputNonBuffered (Dir As String, FileName As String, Append As Boolean) As OutputStream
    Dim f As JavaObject
    f.InitializeNewInstance("java.io.File", Array(Dir, FileName))
    Dim out As JavaObject
    out.InitializeNewInstance("java.io.FileOutputStream", Array(f, Append))
    Return out
End Sub

Private Sub OpenInputNonBuffered (Dir As String, FileName As String) As InputStream
    Dim f As JavaObject
    f.InitializeNewInstance("java.io.File", Array(Dir, FileName))
    Dim in As JavaObject
    in.InitializeNewInstance("java.io.FileInputStream", Array(f))
    Return in
End Sub

The File methods add a buffer which might be problematic in this case.
Thanks for the code, I was investigating in the same direction, unfortunately this doesn't do the trick yet :(
 
Upvote 0

MM2forever

Active Member
Licensed User
Longtime User
Okay so after not getting anywhere trying to read a pipe I switched to using the small command line tool
Winsocat (https://github.com/firejox/WinSocat) where you can pipe between named pipes and a tcp port. I am calling it like this as a shell command:
B4X:
winsocat TCP-LISTEN:0.0.0.0:7777 NPIPE:HmiRuntime

then I just communicate with the pipe as if it was a basic TCP socket. Not the most sleak solution and kind of defeating the purpose of a named pipe I guess but if it works it works I guess...
 
Upvote 0
Top