Linux/Mono环境下使用AnonymousPipeClientStream遇权限异常问题
问题分析与解决
你的代码在Windows环境正常运行,但Linux/Mono下创建AnonymousPipeClientStream时抛出UnauthorizedAccessException,核心有两个关键问题:
1. 管道方向与流类型不匹配
服务器端创建的是PipeDirection.In(表示服务器从管道读取数据),对应的客户端应向管道写入数据(PipeDirection.Out)。但你的客户端代码用StreamReader读取一个Out方向的管道,Windows因兼容性宽松未报错,但Mono遵循严格的管道语义,直接导致句柄权限错误。
2. Mono下匿名管道的句柄处理细节
Linux/Mono环境中,匿名管道的句柄本质是Unix文件描述符,GetClientHandleAsString()返回的是描述符的数字字符串(如"3"),客户端创建AnonymousPipeClientStream时需确保:
- 管道方向与读写逻辑完全匹配
- 子进程已正确继承文件描述符(你的代码中
UseShellExecute=false和HandleInheritability.Inheritable配置正确,这部分无问题)
修正后的代码
using System.Diagnostics; using System.IO.Pipes; using System.Reflection; using System.IO; using System; namespace pipetest { class Program { static void Main(string[] args) { if (args.Length > 0) { // 客户端:向管道写入数据,对应服务器的In方向 using var pipeClient = new AnonymousPipeClientStream( PipeDirection.Out, args[0]); using var pipeWriter = new StreamWriter(pipeClient); Console.WriteLine($"客户端拿到的句柄:{args[0]}"); pipeWriter.WriteLine("来自客户端的测试数据"); pipeWriter.Flush(); // 确保数据写入管道 } else { // 服务器:从管道读取数据 using var pipeServer = new AnonymousPipeServerStream( PipeDirection.In, HandleInheritability.Inheritable); var setupInfo = new ProcessStartInfo(); setupInfo.FileName = Assembly.GetEntryAssembly().Location; setupInfo.Arguments = pipeServer.GetClientHandleAsString(); setupInfo.UseShellExecute = false; setupInfo.WorkingDirectory = Environment.CurrentDirectory; var process = Process.Start(setupInfo); // 释放服务器端持有的客户端句柄副本,避免资源泄漏 pipeServer.DisposeLocalCopyOfClientHandle(); // 读取客户端发送的数据 using var pipeReader = new StreamReader(pipeServer); var receivedData = pipeReader.ReadLine(); Console.WriteLine($"服务器收到:{receivedData}"); process.WaitForExit(); } } } }
额外注意事项
- 确保Mono版本不低于4.8.0,早期版本对匿名管道的Unix支持存在bug
- Linux下运行时无需额外配置文件权限,普通用户权限即可满足管道创建需求
内容的提问来源于stack exchange,提问作者glopes
相关产品推荐
相关产品推荐

