Page 1 of 1

How to use named pipe with 2 applications?

Posted: Fri Mar 18, 2022 2:29 pm
by novablue
Hello, i am trying to understand this code to have 2 programs communicate with each other:

Code: Select all

EnableExplicit
; Beispielprogramm für Named Pipes (very quick, very dirty ...)
; stbi 2007

#BUFSIZE = 1024
Define PipeName.s = "\\.\pipe\pbsamplepipe"

; Named Pipe einrichten
Define hPipe.i = CreateNamedPipe_(PipeName, #PIPE_ACCESS_DUPLEX, #PIPE_TYPE_MESSAGE | #PIPE_READMODE_MESSAGE | #PIPE_NOWAIT, #PIPE_UNLIMITED_INSTANCES, #BUFSIZE, #BUFSIZE, 0, #Null)
If hPipe = 0
  Debug "Fehler beim Erstellen der Named Pipe" : End
EndIf

; zur Named Pipe verbinden
ConnectNamedPipe_(hPipe, 0)

; in die Pipe schreiben
Define handle.i = OpenFile(#PB_Any, PipeName)
WriteString(handle, "Hello Pipe!", #PB_Ascii)
CloseFile(handle)


; einen Blick in die Pipe werfen
Define BytesAvailable.l = 0
PeekNamedPipe_(hPipe, 0, 0, 0, @BytesAvailable, 0)

; aus der Pipe lesen
Define Buffer.s = Space(BytesAvailable)
Define BytesRead.l = 0
ReadFile_(hPipe, @Buffer, BytesAvailable, @BytesRead, 0)
Debug PeekS(@Buffer, -1, #PB_Ascii)

; aufräumen
DisconnectNamedPipe_(hPipe)
CloseHandle_(hPipe)

End
This seems to be working but i can not figure out how to make this work running 2 separate programs.

Program A Is creating a pipe and writing a message:

Code: Select all

#BUFSIZE = 1024
Define PipeName.s = "\\.\pipe\pbsamplepipe"

; Named Pipe einrichten
Define hPipe.i = CreateNamedPipe_(PipeName, #PIPE_ACCESS_DUPLEX, #PIPE_TYPE_MESSAGE|#PIPE_READMODE_MESSAGE | #PIPE_NOWAIT, #PIPE_UNLIMITED_INSTANCES, #BUFSIZE, #BUFSIZE, 0, #Null)
If hPipe = 0
  Debug "Fehler beim Erstellen der Named Pipe" : End
EndIf

; zur Named Pipe verbinden
ConnectNamedPipe_(hPipe, 0)

; in die Pipe schreiben
Define handle.i = OpenFile(#PB_Any, PipeName)
WriteString(handle, "Hello Pipe!", #PB_Ascii)
CloseFile(handle)

OpenConsole()
Print("waiting")

Repeat : Delay(10) : ForEver
And Program B is supposed to read it but i can not get it to work. i don't receive a text.

Code: Select all

#BUFSIZE = 1024
Define PipeName.s = "\\.\pipe\pbsamplepipe"

; Named Pipe einrichten
Define hPipe.i = CreateNamedPipe_(PipeName, #PIPE_ACCESS_DUPLEX, #PIPE_TYPE_MESSAGE|#PIPE_READMODE_MESSAGE | #PIPE_NOWAIT, #PIPE_UNLIMITED_INSTANCES, #BUFSIZE, #BUFSIZE, 0, #Null)
If hPipe = 0
  Debug "Fehler beim Erstellen der Named Pipe" : End
EndIf

; zur Named Pipe verbinden
ConnectNamedPipe_(hPipe, 0)

; einen Blick in die Pipe werfen
PeekNamedPipe_(hPipe, 0, 0, 0, @BytesAvailable, 0)

; aus der Pipe lesen
Define Buffer.s = Space(BytesAvailable)
Define BytesRead.l = 0
ReadFile_(hPipe, @Buffer, BytesAvailable, @BytesRead, 0)

OpenConsole()

Print("Result: " + PeekS(@Buffer, -1, #PB_Ascii))

Repeat : Delay(10) : ForEver

Re: How to use named pipe with 2 applications?

Posted: Fri Mar 18, 2022 8:13 pm
by Caronte3D
I never used that pipes, but if you wait on the second program until something is received, you get the response:

Code: Select all

While BytesAvailable=0
  PeekNamedPipe_(hPipe, 0, 0, 0, @BytesAvailable, 0)
  Delay(1)
Wend

Re: How to use named pipe with 2 applications?

Posted: Sat Mar 19, 2022 9:51 am
by mk-soft
I have also tried it with pipes, which also works. But it is easier to use the UDP network protocol

Here is an example
Link: UDP Local Network Short Text Sending

Re: How to use named pipe with 2 applications?

Posted: Mon Mar 21, 2022 5:53 pm
by bgeraghty
Hi There,

I recently created a quick program which does this. The program runs once as NT\SYSTEM and once as the user, and uses named pipes to communicate between the two programs, with a kind of blocking-socket type communication model. This could be changed so that it is 2 separate programs under the same user account.

https://github.com/bgeraghty/cwc-fronts ... ntstage.pb

Edit: This may be more than you need, so I'll just drop the two important functions that both programs should have. (Removing Windows Session-Related Stuff)

Code: Select all



Procedure.b NamedPipe_SendStr(PipeName$, StringData$)
  Protected Result.b = #False
  Protected Size = Len(StringData$)
  Protected BytesWritten.l
  Protected Res = WaitNamedPipe_(PipeName$, #Null)
  If Res
    Protected hFile = CreateFile_(PipeName$, #GENERIC_READ | #GENERIC_WRITE, 0, #Null, #OPEN_EXISTING,0, #Null)
    If hFile
      WriteFile_(hFile, @StringData$, Size, @BytesWritten, 0)
      If BytesWritten
        Result = #True
      EndIf
      FlushFileBuffers_(hFile)
      CloseHandle_(hFile)
    EndIf
  EndIf
  ProcedureReturn Result
EndProcedure

Procedure.s NamedPipeServer_ListenStr(PipeName$)
  Protected Result.s = ""
  Protected Recv$ = Space(PBufSize) 
  Protected BytesRead ; BytesRead
  Protected PipeHandle = CreateNamedPipe_(PipeName$, #PIPE_ACCESS_DUPLEX, #PIPE_TYPE_MESSAGE | #PIPE_READMODE_MESSAGE, 1, PBufSize, PBufSize, 3000, #Null) ; #PIPE_ACCESS_DUPLEX = 3
  If PipeHandle
    Protected Client = ConnectNamedPipe_(PipeHandle, #Null)
    If Client
      ReadFile_(PipeHandle, @Recv$, Len(Recv$), @BytesRead, 0)
      If Recv$ <> ""
        Result = Trim(Recv$)
      EndIf
      FlushFileBuffers_(PipeHandle)
      DisconnectNamedPipe_(PipeHandle)         
      CloseHandle_(PipeHandle)
    EndIf
  EndIf
  ProcedureReturn Result
EndProcedure

Call NamedPipeServer_ListenStr("\\.\pipe\pbsamplepipe") In One program, and then NamedPipe_SendStr("\\.\pipe\pbsamplepipe", "Hello From Other Program").

Since the ListenStr function is blocking, you might want to call it from a Thread if the program has other things to be doing. When it receives the data, it then un-blocks and returns with the string.

Re: How to use named pipe with 2 applications?

Posted: Sun Mar 27, 2022 11:00 pm
by novablue
Thanks guys that helped a lot. :D