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?
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.
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();
}
}
SetLastError = True
on the DllImport
to see what the underlying error is. –
Furnace _get_osfhandle
is part of the Universal CRT, not the Windows API. It doesn't set the calling thread's last error code. Asking the CLR to preserve it for you will have it preserve a meaningless value. –
Artina © 2022 - 2024 — McMap. All rights reserved.