How to use named pipe with 2 applications?

Just starting out? Need help? Post your questions and find answers here.
novablue
Enthusiast
Enthusiast
Posts: 165
Joined: Sun Nov 27, 2016 6:38 am

How to use named pipe with 2 applications?

Post 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
User avatar
Caronte3D
Addict
Addict
Posts: 1055
Joined: Fri Jan 22, 2016 5:33 pm
Location: Some Universe

Re: How to use named pipe with 2 applications?

Post 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
User avatar
mk-soft
Always Here
Always Here
Posts: 5406
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: How to use named pipe with 2 applications?

Post 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
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
bgeraghty
User
User
Posts: 52
Joined: Wed Apr 02, 2014 12:45 am
Location: irc.ibotched.it:+6697
Contact:

Re: How to use named pipe with 2 applications?

Post 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.
SolveMyIssue_() - No QuickHelp available.
novablue
Enthusiast
Enthusiast
Posts: 165
Joined: Sun Nov 27, 2016 6:38 am

Re: How to use named pipe with 2 applications?

Post by novablue »

Thanks guys that helped a lot. :D
Post Reply