8

I'm trying to create a two-way communication channel between two programs (one in Python and another in C#)

When I create a named pipe between two C# programs or two Python programs, everything is OK, but when I try to (for example) connect to the C# server from Python code, it does not work:

C# code:

NamedPipeServerStream server = new NamedPipeServerStream(
    "Demo", PipeDirection.InOut, 100, PipeTransmissionMode.Byte,
    PipeOptions.None, 4096, 4096)

If I use win32pipe in Python, code blocks on ConnectNamedPipe (it never returns)

p = win32pipe.CreateNamedPipe(
    r'\\.\pipe\Demo',
    win32pipe.PIPE_ACCESS_DUPLEX,
    win32pipe.PIPE_TYPE_BYTE | win32pipe.PIPE_WAIT,
    1, 65536, 65536,
    300,
    None)
win32pipe.ConnectNamedPipe(p)

If I use open function, it just establishes a connection, but nothing occurs:

open( '\\\\.\\pipe\\Demo', 'r+b' )

Now if I close the Python program, C# server receives just one data item from Python and a System.IO.IOException raises with "Pipe is broken" message

Am I doing anything wrong ?

1

3 Answers 3

11

According to MS, ConnectNamedPipe is the "server-side function for accepting a connnection". That's why it never returns - it's waiting for a connection from a client. Here's some sample code showing C# as the server and python as the client:

C#:

using (var server = new NamedPipeServerStream("Demo"))
{
    server.WaitForConnection();

    using (var stream = new MemoryStream())
    using (var writer = new BinaryWriter(stream))
    {
        writer.Write("\"hello\"");
        server.Write(stream.ToArray(), 0, stream.ToArray().Length);
    }

    server.Disconnect();
}

python:

import win32file
fileHandle = win32file.CreateFile(
    "\\\\.\\pipe\\Demo", 
    win32file.GENERIC_READ | win32file.GENERIC_WRITE, 
    0, 
    None, 
    win32file.OPEN_EXISTING, 
    0, 
    None)
left, data = win32file.ReadFile(fileHandle, 4096)
print(data)  # "hello"
Sign up to request clarification or add additional context in comments.

2 Comments

This works like a charm :) Thanks for saving a lot of my time, 8 years later :)
Indeed, a very simple and working example! I would just add one minor thing which took me some time. In this example, both processes needs to run with same elevated rights, otherwise you will get ERROR_ACCESS_DENIED.
1

OK, I fixed the problem. I should seek to position 0 of buffer.

My Python code:

    win32file.WriteFile(CLIENT_PIPE,"%d\r\n"%i ,None)
    win32file.FlushFileBuffers(CLIENT_PIPE)
    win32file.SetFilePointer(CLIENT_PIPE,0,win32file.FILE_BEGIN)
    i,s = win32file.ReadFile(CLIENT_PIPE,10,None)

Comments

0

I think you are meant to use win32pipe.popen, not open.

Also try: pipe.flush(), pipe.read(), and time.sleep(0.01). Sometimes IPC takes a while to sync up.

I don't really know, that's my experience with the subprocess pipes. win32pipe might be different.

2 Comments

I used win32pipe.popen. Nothing changed Have you managed to create a named pipe between Python and .NET ? I don't know why win32pipe.ConnectNamedPipe(p) never returns
I also used win32file, but now the connection establishes but WriteFile does not work (Yes, I've also flushed the buffer)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.