C#使用Named Pipes触发Win32Exception:找不到指定文件求助
命名管道Win32Exception“找不到指定文件”的原因及修复
核心错误原因
- 重复使用已关闭的管道流实例:你的
WriteString方法每次调用都会先连接管道,然后立即关闭流。一旦NamedPipeClientStream被关闭,该实例就彻底失效,无法再次用于连接管道。后续调用Connect()时,失效的实例无法关联到实际存在的管道资源,从而触发“找不到指定文件”的Win32Exception。 - 路径写法不规范(非致命但易混淆):代码中使用
//.//pipe//LiveSplit作为路径,虽然能被解析,但C#中更规范的写法是用双反斜杠转义(\\\\.\\pipe\\LiveSplit)或字符串字面量(@"\\.\pipe\LiveSplit"),避免转义逻辑出错。
修复方案
短连接场景下,最稳妥的方式是每次通信时创建新的NamedPipeClientStream实例,并用using语句自动管理资源,确保流正确释放。修改后的代码如下:
internal class SplitManager { public static void startRun() { Debug.Log("[PIPE]: start"); WriteString("start"); } public static void performSplit() { Debug.Log("[PIPE]: split"); WriteString("split"); } private static void WriteString(string str) { // 每次通信创建全新的管道客户端实例 using (var pipeClientStream = new NamedPipeClientStream(@"\\.\pipe\LiveSplit")) { pipeClientStream.Connect(); new StreamString(pipeClientStream).WriteString(str); // using块会自动关闭并释放流资源,无需手动调用Close() } } } // StreamString类保持不变 public class StreamString { public StreamString(Stream ioStream) { this.ioStream = ioStream; this.streamEncoding = new UnicodeEncoding(); } public string ReadString() { int num = this.ioStream.ReadByte() * 256; num += this.ioStream.ReadByte(); byte[] array = new byte[num]; this.ioStream.Read(array, 0, num); return this.streamEncoding.GetString(array); } public int WriteString(string outString) { byte[] bytes = this.streamEncoding.GetBytes(outString); int num = bytes.Length; if (num > 65535) { num = 65535; } this.ioStream.WriteByte((byte)(num / 256)); this.ioStream.WriteByte((byte)(num & 255)); this.ioStream.Write(bytes, 0, num); this.ioStream.Flush(); return bytes.Length + 2; } private Stream ioStream; private UnicodeEncoding streamEncoding; }
额外说明
- 移除了原有的
initialize方法,因为提前创建流实例并无必要,反而会引发重复使用失效实例的问题。 using语句确保管道流在通信完成后自动释放,避免资源泄漏和无效实例复用的问题。
内容的提问来源于stack exchange,提问作者Kapilarny YT
相关产品推荐
相关产品推荐

