问题
I have a legacy app where it reads message from a client program from file descriptor 3. This is an external app so I cannot change this. The client is written in C#. How can we open a connection to a specific file descriptor in C#? Can we use something like AnonymousPipeClientStream()? But how do we specify the file descriptor to connect to?
回答1:
Unfortunately, you won't be able to do that without P/Invoking to the native Windows API first.
First, you will need to open your file descriptor with a native P/Invoke call. This is done by the OpenFileById WINAPI function. Here's how to use it on MSDN, here's an other link explaining it in detail on the MSDN forums, and here's some help (pinvoke.net) on how to construct your P/Invoke call.
Once you got the file handle, you need to wrap it in a SafeFileHandle, this time in safe, managed C#:
// nativeHandle is the WINAPI handle you have acquired with the P/Invoke call
SafeFileHandle safeHandle = new SafeFileHandle(nativeHandle, true);
Now you can open the file stream directly:
Stream stream = new FileStream(safeHandle, FileAccess.ReadWrite);
And from this point you can use it as any other file or stream in C#. Don't forget to dispose your objects once you're done.
回答2:
I was able to solve the same issue by using _get_osfhandle. Example:
using System;
using System.IO;
using Microsoft.Win32.SafeHandles;
using System.Runtime.InteropServices;
class Comm : IDisposable
{
[DllImport("MSVCRT.DLL", CallingConvention = CallingConvention.Cdecl)]
extern static IntPtr _get_osfhandle(int fd);
public readonly Stream Stream;
public Comm(int fd)
{
var handle = _get_osfhandle(fd);
if (handle == IntPtr.Zero || handle == (IntPtr)(-1) || handle == (IntPtr)(-2))
{
throw new ApplicationException("invalid handle");
}
var fileHandle = new SafeFileHandle(handle, true);
Stream = new FileStream(fileHandle, FileAccess.ReadWrite);
}
public void Dispose()
{
Stream.Dispose();
}
}
来源:https://stackoverflow.com/questions/245827/opening-pipe-connection-to-a-file-descriptor-in-c-sharp