【问题标题】:set named pipe message mode设置命名管道消息模式
【发布时间】:2013-06-09 14:10:10
【问题描述】:

我有以下代码:

//...
SafeFileHandle handle = NativeMethods.CreateFile(pipeName, FileAccess.ReadWrite, FileShare.None, IntPtr.Zero, FileMode.Open, FileAttributes.Normal, IntPtr.Zero);
if (handle.IsInvalid)
    continue;
uint mode = (uint)PipeMode.ReadModeMessage; // mode==2
bool result = NativeMethods.SetNamedPipeHandleState(handle, ref mode, IntPtr.Zero, IntPtr.Zero);
//...

问题是对“SetNamedPipeHandleState”的调用失败:结果为假,GetLastError() 返回 5 (ERROR_ACCESS_DENIED)。除此之外,管道工作得很好——我可以读写数据。当然,除了它不在消息模式下工作 - 例如。两个 WriteFile 消息调用的内容由单个 ReadFile 调用读取。我在这里做错了什么?

【问题讨论】:

    标签: c# .net-2.0 pipe named-pipes


    【解决方案1】:

    CreateFile 打开已由其他充当管道服务器的东西创建的命名管道的客户端。您没有在问题中告诉我们您的管道是如何创建的。只有在管道服务器创建管道时将PipeMode 指定为PIPE_TYPE_MESSAGE,管道才会在消息模式下工作。

    如果管道是以消息模式创建的,那么管道客户端可以选择是以消息模式读取还是以字节模式读取。如果管道未处于消息模式,则管道客户端不会尝试将读取模式设置为消息 (PIPE_READMODE_MESSAGE),因为它不会更改管道模式。

    您也没有向我们展示您是如何实现您的NativeMethods,但如果您的CreateFile 参数直接映射到Win32 的CreateFile 函数的参数,那么您只是请求FILE_READ_DATA 和@987654330 @ 管道句柄的访问权限。这些权限不足以让您调用SetNamedPipeHandleState,这解释了访问被拒绝错误。见the Win32 API documentation

    句柄必须具有对命名管道的 GENERIC_WRITE 访问权限 只写或读/写管道,或者它必须有 GENERIC_READ 和 只读管道的 FILE_WRITE_ATTRIBUTES 访问权限。

    【讨论】:

    • 我已经在对 Hans Passant 的回答(已被删除)的评论中写道,管道是在消息模式下创建的。我认为 FileAccess.ReadWrite 会转换为与 GENERIC_READ|GENERIC_WRITE 相同的内容,但是(正如您所指出的)事实并非如此。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多