Открытие канала соединения с файловым дескриптором в C # - PullRequest
5 голосов
/ 29 октября 2008

У меня есть старое приложение, в котором оно читает сообщение из клиентской программы из файлового дескриптора 3. Это внешнее приложение, поэтому я не могу его изменить. Клиент написан на C #. Как мы можем открыть соединение с определенным дескриптором файла в C #? Можем ли мы использовать что-то вроде AnonymousPipeClientStream ()? Но как нам указать дескриптор файла для подключения?

Ответы [ 2 ]

5 голосов
/ 30 января 2009

К сожалению, вы не сможете сделать это без P / Invoking для собственного Windows API.

Во-первых, вам нужно открыть дескриптор файла с помощью собственного вызова P / Invoke. Это делается с помощью функции OpenFileById WINAPI. Вот как это использовать на MSDN, вот другая ссылка , подробно объясняющая это на форумах MSDN, и вот некоторая помощь (pinvoke.net) о том, построить ваш P / Invoke вызов.

Как только вы получите дескриптор файла, вам нужно обернуть его в SafeFileHandle, на этот раз в безопасный, управляемый C #:

// nativeHandle is the WINAPI handle you have acquired with the P/Invoke call
SafeFileHandle safeHandle = new SafeFileHandle(nativeHandle, true);

Теперь вы можете открыть поток файлов напрямую:

Stream stream = new FileStream(safeHandle, FileAccess.ReadWrite);

И с этого момента вы можете использовать его как любой другой файл или поток в C #. Не забудьте утилизировать свои объекты, как только вы закончите.

1 голос
/ 19 апреля 2017

Мне удалось решить ту же проблему с помощью _get_osfhandle. Пример:

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();
    }       
}
...