MemoryMappedFile使用小结
2011-05-14 01:16
459 查看
对于Windows进程之间的数据交换,最简单的方式莫过于使用.NET4框架MemoryMappedFile,关于MemoryMappedFile,MSDN上面有很好的讲解和实例,参见: http://msdn.microsoft.com/zh-cn/library/dd997372.aspx
粗看了一下,似乎很简单,于是照猫画虎的搬进了自己的项目(包括一个服务程序(Widows Services)和一个服务监控程序(Winform),需要实现这两个进程间的数据交换),很快完成了编码,运行一下,服务程序运行OK,启动监控程序,异常发生:“Exception:无法访问的路径!”异常发生在监控程序MemoryMappedFile.CreateOrOpen(MEMORY_NAME, _memorySize, MemoryMappedFileAccess.ReadWrite)的时候;显然,系统认为监控程序无权打开由服务程序创建的内存映射文件,上网google,证实了我的猜测:Windows服务程序与一般的桌面应用程序运行在不同的安全上下文中。
于是修改服务程序,加入调试代码:
MemoryMappedFile mmf = _shmManager.Mmf;
MemoryMappedFileSecurity mc = mmf.GetAccessControl();
foreach (AccessRule<MemoryMappedFileRights> ar in
mc.GetAccessRules(true, true, typeof(System.Security.Principal.NTAccount)))
{
_logger.Info("user:"+ ar.IdentityReference);
_logger.Info("right:"+ ar.Rights);
_logger.Info("type:"+ ar.AccessControlType);
}
重新运行服务程序,查看日志输出信息:
2011-03-1417:46:20,059 -- User: NT AUTHORITY\SYSTEM
2011-03-1417:46:20,059 -- Type: Allow
2011-03-1417:46:20,059 -- Rights: 983071
2011-03-1417:46:20,059 -- User: BUILTIN\Administrators
2011-03-1417:46:20,059 -- Type: Allow
2011-03-1417:46:20,059 -- Rights: CopyOnWrite, ReadExecute, ReadPermissions
试验结果表明:默认情况下,由Windows服务进程创建的内存映射文件对NT AUTHORITY\SYSTEM账号赋予完全控制权限,而内置的管理员组有BUILTIN\Administrators有CopyOnWrite, ReadExecute, ReadPermissions的权限;而我的系统是用本地Administrator登录的,应该也属于BUILTIN\Administrators组,看来管理员组的这些权限还是不足以去CreateOrOpen(...)的,考虑到我的监控程序还需要写内存映射文件,需要更高的权限才行,于是修改服务程序,在创建内存映射文件时赋予Administrator完全控制的权限,以下是代码:
mmf = MemoryMappedFile.CreateOrOpen(MEMORY_NAME, _memorySize,
MemoryMappedFileAccess.ReadWrite);
bool exist= false;
string user = System.Net.Dns.GetHostName()+"\\Administrator";
AccessRule<MemoryMappedFileRights> rule = new AccessRule<MemoryMappedFileRights>(
user,
MemoryMappedFileRights.FullControl,
AccessControlType.Allow);
MemoryMappedFileSecurity msc = mmf.GetAccessControl();
foreach (AccessRule<MemoryMappedFileRights> ar in msc.GetAccessRules(true, true,
typeof(NTAccount)))
{
if(ar.IdentityReference == rule.IdentityReference &&
ar.AccessControlType == rule.AccessControlType &&
ar.Rights == rule.Rights)
{
exist= true;
break;
}
}
if(!exist)
{
msc.AddAccessRule(rule);
mmf.SetAccessControl(msc);
}
再次编译,运行服务程序,正常,运行监控程序,正常, OK,问题解决~
粗看了一下,似乎很简单,于是照猫画虎的搬进了自己的项目(包括一个服务程序(Widows Services)和一个服务监控程序(Winform),需要实现这两个进程间的数据交换),很快完成了编码,运行一下,服务程序运行OK,启动监控程序,异常发生:“Exception:无法访问的路径!”异常发生在监控程序MemoryMappedFile.CreateOrOpen(MEMORY_NAME, _memorySize, MemoryMappedFileAccess.ReadWrite)的时候;显然,系统认为监控程序无权打开由服务程序创建的内存映射文件,上网google,证实了我的猜测:Windows服务程序与一般的桌面应用程序运行在不同的安全上下文中。
于是修改服务程序,加入调试代码:
MemoryMappedFile mmf = _shmManager.Mmf;
MemoryMappedFileSecurity mc = mmf.GetAccessControl();
foreach (AccessRule<MemoryMappedFileRights> ar in
mc.GetAccessRules(true, true, typeof(System.Security.Principal.NTAccount)))
{
_logger.Info("user:"+ ar.IdentityReference);
_logger.Info("right:"+ ar.Rights);
_logger.Info("type:"+ ar.AccessControlType);
}
重新运行服务程序,查看日志输出信息:
2011-03-1417:46:20,059 -- User: NT AUTHORITY\SYSTEM
2011-03-1417:46:20,059 -- Type: Allow
2011-03-1417:46:20,059 -- Rights: 983071
2011-03-1417:46:20,059 -- User: BUILTIN\Administrators
2011-03-1417:46:20,059 -- Type: Allow
2011-03-1417:46:20,059 -- Rights: CopyOnWrite, ReadExecute, ReadPermissions
试验结果表明:默认情况下,由Windows服务进程创建的内存映射文件对NT AUTHORITY\SYSTEM账号赋予完全控制权限,而内置的管理员组有BUILTIN\Administrators有CopyOnWrite, ReadExecute, ReadPermissions的权限;而我的系统是用本地Administrator登录的,应该也属于BUILTIN\Administrators组,看来管理员组的这些权限还是不足以去CreateOrOpen(...)的,考虑到我的监控程序还需要写内存映射文件,需要更高的权限才行,于是修改服务程序,在创建内存映射文件时赋予Administrator完全控制的权限,以下是代码:
mmf = MemoryMappedFile.CreateOrOpen(MEMORY_NAME, _memorySize,
MemoryMappedFileAccess.ReadWrite);
bool exist= false;
string user = System.Net.Dns.GetHostName()+"\\Administrator";
AccessRule<MemoryMappedFileRights> rule = new AccessRule<MemoryMappedFileRights>(
user,
MemoryMappedFileRights.FullControl,
AccessControlType.Allow);
MemoryMappedFileSecurity msc = mmf.GetAccessControl();
foreach (AccessRule<MemoryMappedFileRights> ar in msc.GetAccessRules(true, true,
typeof(NTAccount)))
{
if(ar.IdentityReference == rule.IdentityReference &&
ar.AccessControlType == rule.AccessControlType &&
ar.Rights == rule.Rights)
{
exist= true;
break;
}
}
if(!exist)
{
msc.AddAccessRule(rule);
mmf.SetAccessControl(msc);
}
再次编译,运行服务程序,正常,运行监控程序,正常, OK,问题解决~
相关文章推荐
- windows服务与其他进程使用MemoryMappedFile
- 为何要在Java中使用内存映射文件(Memory Mapped File)或者MappedByteBuffer
- 虚拟内存(VirtualAlloc),堆(HeapAlloc/malloc/new)和Memory Mapped File
- MemoryMappedFile 在 Mono in Linux 的开发笔记
- ASP.NET 2.0之HtmlInputFile控件使用小结
- 初探ELK-filebeat使用小结
- PHP中file_exists使用中遇到的问题小结
- 虚拟内存(VirtualAlloc),堆(HeapAlloc/malloc/new)和Memory Mapped File
- 缓存,使用MAVEN时出现OutOfMemory错误(小结笔记一)
- 虚拟内存(VirtualAlloc),堆(HeapAlloc/malloc/new)和Memory Mapped File
- RandomAccessFile使用小结
- 封装:内存镜像文件(MemoryMappedFile)封装,一维二维三维定点访问
- Java中Stream和NIO的Memory-mapped File的I/O性能对比
- Oracle 常用的dump(Memory Dumps/File Dumps/Trace 文件使用示例)
- 使用dockerfile定制对象小结
- MemoryMappedFile 在 Mono in Linux 的开发笔记
- 构建高性能java程序-使用mapped file创建超大的矩阵
- 虚拟内存(VirtualAlloc),堆(HeapAlloc/malloc/new)和Memory Mapped File
- Android O SYSTEM_UID应用无法使用FileProvider问题小结
- 内存操作类(共享映射文件 MemoryMappedFile)