我开发了一个使用共享内存的Windows应用程序---即内存映射文件,用于进程间通信.我有一个Windows服务,它执行一些处理并定期将数据写入内存映射文件.我有一个单独的Windows应用程序,它从内存映射文件中读取并显示信息.该应用程序在Windows XP,XP Pro和Server 2003上按预期工作,但不在Vista上.
我可以看到写入内存映射文件的数据是由Windows服务正确发生的,因为我可以使用文本编辑器打开文件并查看存储的消息,但"消费者"应用程序无法从文件中读取.这里需要注意的一件有趣的事情是,如果我关闭使用者应用程序并重新启动它,它会消耗先前写入内存映射文件的消息.
另外,另一个奇怪的事情是当我使用远程桌面连接到Windows主机并通过远程桌面调用/使用消费者应用程序时,我得到相同的行为.但是,如果我调用远程桌面并使用以下命令连接到目标主机的控制台会话:mstsc -v:servername /F -console
,一切正常.
这就是为什么我认为问题与权限有关.任何人都可以评论这个吗?
编辑:
我用来创建内存映射文件的ACL和同步访问的Mutex对象如下:
TCHAR * szSD = TEXT("D:")
TEXT("(A;;RPWPCCDCLCSWRCWDWOGAFA;;;S-1-1-0)")
TEXT("(A;;GA;;;BG)")
TEXT("(A;;GA;;;AN)")
TEXT("(A;;GA;;;AU)")
TEXT("(A;;GA;;;LS)")
TEXT("(A;;GA;;;RD)")
TEXT("(A;;GA;;;WD)")
TEXT("(A;;GA;;;BA)");
我认为这可能是问题的一部分.
所以我找到了解决问题的方法:
在Windows XP上,所有已命名的内核对象(如互斥锁,信号量和内存映射对象)都存储在同一名称空间中.因此,当不同用户会话中的不同进程使用它的名称引用特定对象时,它们将获得该对象的句柄.但是,作为安全预防措施,Windows终端服务为从其会话中启动的进程引用的内核对象创建单独的命名空间.Windows Vista也内置了这种行为,这就是为什么我的应用程序无法在Vista上正常运行的原因.为了详细说明,我有一个在空会话中运行的Windows服务和一个在用户会话中运行的应用程序,因此我的命名对象是在不同的命名空间中创建的.
这个问题的快速解决方法是使用全局命名空间,将"Global"添加到我使用的每个内核对象名称并完成操作.