我正在开发一个开源.NET程序集(WinSCP .NET assembly),该程序集会生成一个 native (C++)应用程序,并通过事件和文件映射对象与其进行通信。
程序集使用Process
类生成应用程序,没有特殊设置。程序集创建很少的事件(使用EventWaitHandle
)和文件映射(使用PInvoked CreateFileMapping
),应用程序使用OpenEvent
和OpenFileMapping
来“打开”这些事件。
在大多数情况下,它都能正常工作。但是现在我有一个用户使用Windows Server 2008 R2 64位上的ASPX应用程序中的程序集。
在他的情况下,OpenEvent
和OpenFileMapping
都返回NULL
,而GetLastError
返回ERROR_ACCESS_DENIED
。
我试图通过显式地授予当前用户对事件对象和应用程序代码必要的权限来改进汇编代码,以根据Microsoft Docs example仅要求真正需要的访问权限(而不是原始EVENT_ALL_ACCESS
)。它没有帮助。因此,我什至不用为文件映射对象尝试相同的操作。
创建事件的C#代码为:
EventWaitHandleSecurity security = new EventWaitHandleSecurity();
string user = Environment.UserDomainName + "\\" + Environment.UserName;
EventWaitHandleAccessRule rule;
rule =
new EventWaitHandleAccessRule(
user, EventWaitHandleRights.Synchronize | EventWaitHandleRights.Modify,
AccessControlType.Allow);
security.AddAccessRule(rule);
rule =
new EventWaitHandleAccessRule(
user, EventWaitHandleRights.ChangePermissions, AccessControlType.Deny);
security.AddAccessRule(rule);
new EventWaitHandle(
false, EventResetMode.AutoReset, name, out createdNew, security);
“打开”事件的C++代码是:OpenEvent(EVENT_MODIFY_STATE, false, name);
(对于其他事件,访问级别为SYNCHRONIZE
,具体取决于需求)。我也尝试将
Global\
前缀添加到对象名称。不出所料,这并不能解决问题。有谁知道导致
OpenEvent
(或CreateFileMapping
)“访问被拒绝”错误的原因是什么? 最佳答案
我的猜测是该事件是由匿名用户还是已登录用户创建的,具体取决于网站的设置方式。但是子流程正在与基本流程用户一起启动。可以通过使用进程监视器并查看事件句柄的acl来查看创建者是谁,以进行检查。然后查看子进程以查看其运行身份。
如果是这种情况,那么您可以更新事件的acl以包括基本过程。除此之外,您可能仍需要以“global”作为前缀,以确保可以跨用户边界使用该事件。