7

我开发了一个使用共享内存的 Windows 应用程序——即——用于进程间通信的内存映射文件。我有一个 Windows 服务,它进行一些处理并定期将数据写入内存映射文件。我有一个单独的 Windows 应用程序,它从内存映射文件中读取并显示信息。该应用程序在 Windows XP、XP Pro 和 Server 2003 上按预期工作,但在 Vista 上却不行。

我可以看到 Windows 服务正在正确地写入内存映射文件的数据,因为我可以使用文本编辑器打开文件并查看存储的消息,但“消费者”应用程序无法从文件中读取。这里要注意的一件有趣的事情是,如果我关闭消费者应用程序并重新启动它,它会使用之前写入内存映射文件的消息。

另外,另一个奇怪的事情是,当我使用远程桌面连接到 Windows 主机并通过远程桌面调用/使用消费者应用程序时,我得到了相同的行为。但是,如果我调用远程桌面并使用以下命令连接到目标主机的控制台会话:mstsc -v:servername /F -console,一切正常。

所以这就是为什么我认为问题与权限有关。任何人都可以对此发表评论吗?

编辑:

我用来创建内存映射文件和同步访问的 Mutex 对象的 ACL 如下:

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)"); 

我认为这可能是问题的一部分。

4

4 回答 4

9

所以我找到了解决我的问题的方法:

在 Windows XP 上,所有命名的内核对象,例如互斥体、信号量和内存映射对象都存储在同一个命名空间中。因此,当不同用户会话中的不同进程使用其名称引用特定对象时,它们会获得该对象的句柄。但是,作为安全预防措施,Windows 终端服务为从其会话中启动的进程引用的内核对象创建一个单独的命名空间。Windows Vista 也内置了这种行为,所以这就是我的应用程序在 Vista 上无法正常工作的原因。详细地说,我有一个在空会话中运行的 Windows 服务和一个在用户会话中运行的应用程序,因此我的命名对象是在单独的命名空间中创建的。

这个问题的快速解决方法是通过在我使用的每个内核对象名称前面加上“Global\”来使用全局命名空间,这样就可以了。

于 2008-10-08T20:30:18.340 回答
3

前缀“Global\”可能不适用于共享内存。有关解决方案,请参阅“会话 0 隔离对 Windows Vista 中的服务和驱动程序的影响”

于 2008-10-09T01:02:37.433 回答
1

您打开共享内存部分的访问权限是什么?尝试FILE_MAP_ALL_ACCESS并按照自己的方式工作。还要确保生产者和消费者之间没有竞争条件——哪一个在创建共享内存?确保在另一个尝试打开它之前创建它。一种方法是在启动子进程之前在父进程中创建该部分 - 如果您使用的是父/子架构。

您的孩子可能需要在 Vista 上运行提升才能被允许访问共享内存。它也可能与您正在使用的窗口会话有关。服务在会话 0 中运行(我认为),而其他应用程序(特别是如果您通过远程桌面登录)可能在另一个会话中运行。

于 2008-10-06T22:15:13.187 回答
0

您是否尝试过将文件移动到其他位置。尝试将它放在“共享文档”文件夹中,这似乎是 Vista 中最容易访问的文件夹。

于 2008-10-06T22:14:40.347 回答