当前位置: 首页 > 编程语言 > C#

为只读命名管道启用MessageMode时的C#UnauthorizedAccessException(NamedPipeClientStream类)分享

时间:2023-04-10 20:11:10 C#

C#学习教程:C#UnauthorizedAccessException(NamedPipeClientStream类)当为只读命名管道启用MessageMode时无法使用PipeDirection.In创建此类的实例,然后成功将ReadMode更改为PipeTransmissionMode.Message。尝试这样做会抛出UnauthorizedAccessException。虽然管道通常用于进程之间的通信,但单个进程中的这个简单示例显示了问题:varpipeOut=newNamedPipeServerStream("SomeNamedPipe",PipeDirection.Out,1,PipeTransmissionMode.Message);varpipeIn=newNamedPipeClientStream(".","SomeNamedPipe",PipeDirection.In);pipeIn.Connect();pipeIn.ReadMode=PipeTransmissionMode.Message;尝试设置ReadMode属性时,此代码会抛出UnauthorizedAccessException。在搜索有关此问题的信息时,我在其他地方找到了对它的引用,例如:所有这些帖子都将其称为“怪异”、“怪异”等,但没有解释“为什么”它不起作用,并且两者都提供相同的解决方法,“出于某种奇怪的原因”将管道方向设置为InOut使其工作。确实,这确实使它起作用,但是它需要从根本上将管道两端的定义更改为全双工,而不是单向,我认为这是一个非常糟糕的方法,除非您能够更改客户端和服务器,它甚至可能不可能。我的问题是,为什么在入站管道上启用消息模式会导致异常,是否有比将管道更改为双向模式更好的解决方法?查看Microsoft参考源,我可以看到设置ReadMode属性只是调用win32SetNamedPipeHandleState函数来执行操作,此调用的错误将作为异常抛出。根据文档SetNamedPipeHandleState函数,它声明了管道句柄,为了调用此函数,句柄必须对只写或读/写管道的命名管道具有GENERIC_WRITE访问权限,或者对只读管道具有GENERIC_READ和FILE_WRITE_ATTRIBUTES访问权限。这就是问题所在。如果我们查看接受PipeDirection设置的NamedPipeClientStream的构造函数,我们会看到它们只请求对PipeDirection.In的GENERIC_READ访问权限和对PipeDirection.In的GENERIC_READ访问权限(或同时对InOut)。这意味着任何以Out或InOut模式打开的管道都可以工作,因为GENERIC_WRITE访问权限足以满足这些情况,但我们需要GENERIC_READ和FILE_WRITE_ATTRIBUTES用于只读管道,NamedPipeClientStream类从不请求。这是类中的缺陷,应由Microsoft纠正。我在此处提交了有关MicrosoftConnect的错误报告:https://connect.microsoft.com/VisualStudio/feedback/details/1825187如果您自己遇到此问题,请投票,它可能有助于加快修复速度。在修复之前(截至2017年3月没有修复),可以通过为NamedPipeClientStream使用不同的构造函数来完全解决这个问题。构造函数的重载将PipeDirection枚举替换为PipeAccessRights枚举,您可以在其中指定要为句柄获取的访问权限的特定组合。然后,构造函数从指定访问权限的组合(“如果指定了ReadData时输出”、“如果指定了WriteData时输出”或“如果指定了它们时为InOut”)导出管道的方向。这意味着,您可以通过像这样简单地更改构造函数行来解决此问题而无需双工管道:varpipeIn=newNamedPipeClientStream("","",PipeDirection.In);为此:varpipeIn=newNamedPipeClientStream("","",PipeAccessRights.ReadData|PipeAccessRights.WriteAttributes,PipeOptions.None,System.Security.Principal.TokenImpersonationLevel.None,System.IO.HandleInheritability.None);如果您使用此备用构造函数作为建议的解决方法,那么结果将与您从构造函数的第一种形式获得的结果相同且无法区分,除了将获得此额外访问权限以便可以启用消息模式。以上就是C#学习教程的全部内容:C#UnauthorizedAccessException(NamedPipeClientStream类)只读命名管道启用MessageMode时。网络收藏不代表立场,如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: