3

When creating named pipes using the NamedPipeClientStream or NamedPipeServerStream classes of dotnet core, the associated "pipe" (which appears to actually be a socket) has "CoreFxPipe_" added to the front of the file name automatically.

Is there a non-hacky way to prevent this behavior? I would simply like the file name to be exactly the name I provide to the constructor.

In the dotnet core documentation, it describes the following constructor:

NamedPipeServerStream(String)
Initializes a new instance of the NamedPipeServerStream class with the specified pipe name.

But, for reasons described above, this description appears to be misleading at best.

SockPastaRock
  • 301
  • 3
  • 13

2 Answers2

3

Solution:

Use an absolute path for the pipe name

Details:

Looking through the source code for NamedPipeClientStream, line 93 reveals that the pipe name is "normalized" with a call to GetPipePath which is a method of the PipeStream class. Looking through the source code for PipeStream, GetPipePath is implemented on line 35.

It seems the method checks "IsPathRooted" (presumably; is the pipe name an absolute path). If it is then it will give you "full control" over defining the path to the socket. Otherwise it will place the socket in /tmp/ and add a prefix of CoreFxPipe_ to the filename.

line 93 https://github.com/dotnet/corefx/blob/master/src/System.IO.Pipes/src/System/IO/Pipes/NamedPipeClientStream.cs

line 35: https://github.com/dotnet/corefx/blob/master/src/System.IO.Pipes/src/System/IO/Pipes/PipeStream.Unix.cs

SockPastaRock
  • 301
  • 3
  • 13
  • This is correct, when I used /tmp/my_named_pipe that is what gets created.. but it is still a socket when you use ls -l to check which might be a problem if the other process you use is not dotnet so is expecting to find a pipe (for example a C console app built with gcc) – andrew pate Aug 05 '23 at 18:29
0

If the OS you are using is unix/ubuntu and you want to use named pipes (mkfifo) rather than streams then here is some C# code for doing that via System.IO.FileStream

using System;
using System.IO;
using System.Threading.Tasks;

// Use unix mkfifo named pipe rather than stream
public class NamedPiper2
{

public static void Create(string pipeName){
    System.Diagnostics.Process process = new System.Diagnostics.Process();
    System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
    startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
    startInfo.FileName = "mkfifo";
    startInfo.Arguments = pipeName;
    process.StartInfo = startInfo;
    process.Start();
    process.WaitForExit();
    Console.WriteLine("Created Named Pipe: " + pipeName); 
}

public static void Close(string pipeName){
    System.Diagnostics.Process process = new System.Diagnostics.Process();
    System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
    startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
    startInfo.FileName = "rm";
    startInfo.Arguments = pipeName;
    process.StartInfo = startInfo;
    process.Start();
    process.WaitForExit();
    Console.WriteLine("Closed Named Pipe: " + pipeName); 
}

public static void Read(string pipeName)
{
    
    // Open the named pipe for reading
    using (FileStream pipeStream = new FileStream(pipeName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
    {
        using (StreamReader reader = new StreamReader(pipeStream))
        {
            bool trucking = true;
            while(trucking){
                var message = reader.ReadLine();
                if(message == null){
                    Task.Delay(1000).Wait();
                }else{
                    Console.WriteLine("Read Received message: " + message); 
                    if(message.Trim() == "bye") trucking = false;
                }                     
            }
        }
    }
}

}

andrew pate
  • 3,833
  • 36
  • 28