Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在C中打开与文件描述符的管道连接#_C#_.net_Winapi_Pinvoke_File Descriptor - Fatal编程技术网

C# 在C中打开与文件描述符的管道连接#

C# 在C中打开与文件描述符的管道连接#,c#,.net,winapi,pinvoke,file-descriptor,C#,.net,Winapi,Pinvoke,File Descriptor,我有一个遗留应用程序,它从文件描述符3读取来自客户端程序的消息。这是一个外部应用程序,因此我无法更改它。客户端是用C#编写的。如何在C#中打开与特定文件描述符的连接?我们可以使用类似AnonymousPipeClientStream()的东西吗?但是我们如何指定要连接到的文件描述符呢?不幸的是,如果不先调用本机Windows API,您将无法做到这一点 首先,需要使用本机p/Invoke调用打开文件描述符。这是由OpenFileById WINAPI函数完成的。在MSDN上,在MSDN论坛上详细

我有一个遗留应用程序,它从文件描述符3读取来自客户端程序的消息。这是一个外部应用程序,因此我无法更改它。客户端是用C#编写的。如何在C#中打开与特定文件描述符的连接?我们可以使用类似AnonymousPipeClientStream()的东西吗?但是我们如何指定要连接到的文件描述符呢?

不幸的是,如果不先调用本机Windows API,您将无法做到这一点

首先,需要使用本机p/Invoke调用打开文件描述符。这是由OpenFileById WINAPI函数完成的。在MSDN上,在MSDN论坛上详细解释它,以及如何构造P/Invoke调用

一旦获得文件句柄,就需要将其包装在一个安全的文件句柄中,这次是在安全的托管C#中:

现在您可以直接打开文件流:

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

从这一点出发,您可以将其用作C#中的任何其他文件或流。完成后别忘了处理对象。

我通过使用解决了同样的问题。例如:

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

这些文件ID是否与C运行时文件描述符相同?此外,OpenByFileId仅在Vista或更高版本上受支持。嘿,Tim,我正在尝试使用您的代码为FD3生成句柄,并且_get_osfhandle返回-1,这会引起注意?@hardkoded:不,不。我建议在
DllImport
上使用
SetLastError=True
来查看潜在的错误。
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();
    }       
}