unauthorizedaccessexception主因是ntfs acl权限不足,需确保文件存在、有fileiopermission且无独占打开;命名映射跨进程通信须名称完全一致、用createoropen、配eventwaithandle同步。

MemoryMappedFile.CreateFromFile 为什么总抛出 UnauthorizedAccessException
权限不足是 Windows 上最常见的报错,尤其在非管理员账户下尝试映射只读文件、系统保护路径(如 C:\Windows)或 NTFS 权限受限的目录时。UnauthorizedAccessException 并不总意味着代码写错了,而是访问控制列表(ACL)没放行。
- 确保目标文件已存在且进程有
FileIOPermission的Read或ReadWrite权限 - 若映射到文件后备(backed)模式,文件不能被其他进程以冲突模式打开(例如另一进程用
FileShare.None独占打开) - 避免映射网络路径(UNC)——
MemoryMappedFile不支持远程文件,会静默失败或抛异常 - 调试时可用
Process Monitor查看具体哪类访问被拒绝(如Desired Access: ReadAttributes)
如何用 CreateOrOpen 配合命名映射实现跨进程通信
命名内存映射文件是 C# IPC 最轻量的方案之一,本质是内核对象共享。关键不在“创建”,而在“名字一致 + 访问同步”。
- 服务端调用
MemoryMappedFile.CreateOrOpen("MyIPCMap", 1024),客户端用完全相同的名称调用同名方法即可连接 - 名字区分大小写,且全局唯一;建议加前缀如
"Global\MyApp_IPC_v1"避免与其他应用冲突 - 必须配合
MemoryMappedViewAccessor才能读写数据,且多个进程不能同时用同一个Accessor实例操作——每个进程需独立.CreateViewAccessor() - 没有内置消息边界,需自行约定协议:比如前 4 字节存长度,后续为 UTF8 字符串;否则容易读到脏数据
MemoryMappedViewAccessor.WriteArray 性能差?改用指针操作更稳
WriteArray<t></t> 和 ReadArray<t></t> 内部做了数组拷贝和类型检查,小数据还行,高频 IPC 场景下 GC 压力和复制开销明显。
- 启用
unsafe后,用Accessor.SafeMemoryMappedViewHandle.DangerousGetHandle()获取句柄,再通过Marshal.UnsafeAddrOfPinnedArrayElement或Span<byte>.DangerousCreate</byte>构建可读写视图 - 务必保证
Accessor生命周期长于指针使用期,否则句柄提前释放会导致AccessViolationException - 简单场景下,直接用
Accessor.WriteInt32(0, value)、Accessor.ReadString(4, Encoding.UTF8)比数组更可控,也避免序列化开销
为什么进程退出后映射还在,新进程连不上同名映射
Windows 内核对象(包括命名 MemoryMappedFile)生命周期由引用计数控制,不是靠进程存活。但常见误操作会让“名字看似相同实则不同”:
- 服务端用
CreateOrOpen创建,客户端却用CreateFromFile—— 后者不认名字,只认文件路径,根本不会去查命名对象表 - 一个进程用
"MyMap",另一个用"myMap"(大小写不同),Windows 视为两个对象 - 未显式调用
Dispose(),导致对象句柄泄漏;重启前可用Handle.exe -a | findstr "Section"查残留句柄 - UWP 应用默认运行在 AppContainer 沙箱中,无法访问普通命名映射,需用
Local\前缀并配置能力声明
实际用下来,最易忽略的是同步点:MemoryMappedFile 本身不提供信号机制。两个进程得额外配 EventWaitHandle 或轮询标志位,否则极易出现“数据已写入但对方还没读”的竞态。










