QueryInterface 失败并显示 E_ACCESSDENIED
以下方法是 DCOM 服务器方法。 COM客户端和服务器运行在不同的WinXP机器上。 COM客户端调用RegisterClient
方法注册回调接口。问题是 QueryInterface
方法失败,错误代码为 E_ACCESSDENIED
。问题的原因可能是什么?
STDMETHODIMP CGEMExtension::RegisterClient(IUnknown** ppGEMExtensionEvents, int* nClientId, int* nResult)
{
HRESULT hRes = (*ppGEMExtensionEvents)->QueryInterface(IID_IGEMExtension,(void**)&pUnknown);
return hRes;
}
The following method is a DCOM server method. The COM client and server is running in different WinXP machines. The COM client calls RegisterClient
method to register callback interface. The problem is QueryInterface
method fails with error code E_ACCESSDENIED
. What could be the reason for the issue?
STDMETHODIMP CGEMExtension::RegisterClient(IUnknown** ppGEMExtensionEvents, int* nClientId, int* nResult)
{
HRESULT hRes = (*ppGEMExtensionEvents)->QueryInterface(IID_IGEMExtension,(void**)&pUnknown);
return hRes;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
当您收到 E_ACCESSDENIED 时,这意味着您遇到了权限问题(不要在防火墙或注册上浪费时间 - 前者会引发错误,告诉您服务不可用,而后者会告诉您该类未注册或所以)。 COM 依赖于 Windows 权限,因此这是您应该关注的。
在您的情况下,如果我正确理解了这种情况,服务器实际上会调用客户端,以获得正确的接口。为此,运行服务器的用户应该在客户端拥有正确的权限。一些建议:
When you get an E_ACCESSDENIED, it means you have a permissions problem (don't waist your time on firewalls or registrations - the former will raise errors telling you the service is not available, and the latter will tell you the class is not registered or so). COM relies on Windows permissions, so this is what you should focus on.
In your case, if I understand the case correctly, the server actually calls the client, in order to get the right interface. For that, the user running the server should have the right permissions on the client side. A few suggestions:
这可能是因为另一台计算机上的正确权限是错误的。检查这一点的最简单方法是使用 secpol 打开日志记录(本地策略、审核策略、打开登录事件和对象访问的日志记录),然后您可以查看是否正在尝试访问另一台计算机。
如果您只是进行测试,那么我建议在组件服务中的 com 对象上使用“以交互用户身份运行”设置,并确保两台计算机上具有相同的用户和相同的密码。然后您必须以普通用户身份在客户端计算机上运行。也可以将用户专门设置为普通用户。
作为调试 DCOM 连接的一般建议:关闭所有防火墙等以确保连接正常工作,然后一项一项地打开安全措施,确保打开正确的端口并且正确的用户拥有正确的端口权限。
This might be because the correct permissions is wrong on the other computer. Simplest way to check this is to turn on logging with secpol (Local Policies, Audit policy, turn on logging of logon events and object access) then you can see if you are trying to access the other machine.
If you are just testing then I would suggest to use the setting "run as interactive user" on the com object in component services and make sure that you have the same user with the same password on both machines. Then you must be running as the common user on the client machine. Spesifically setting the user to the common user is also possible.
As a general advice to debugging DCOM connectivity: Turn off all firewalls and such to make sure that the connection is working, then turn on security measures one by one, making sure that you leave the correct ports open and that the correct users have the correct permissions.
我向您提供我的经验,即使它可能并不直接适用于您的具体情况。
在 64 位的 Windows 7 上,我有一个用 x64 编译的 exe 和一个用 32 位编译的 dll。
COM 对象存在于 dll 内部。
exe(由“普通”用户启动)创建 COM 对象(在同一台计算机上),请求
IUnknown
并且创建成功。然后,exe 通过QueryInterface
请求不同的接口,但失败并显示E_ACCESSDENIED
。如果我“以管理员身份”启动 exe,则
QueryInterface
将返回S_OK
。我没有进一步调查,我怀疑有一些关于 32 位 - 64 位交互的政策。
I give you my experience even if it may not apply directly to your specific case.
On Windows 7 at 64bit I have an exe compiled with x64 and a dll compiled at 32 bit.
A COM object lives inside the dll.
The exe (launched by the "normal" user) creates the COM object (on the same computer) asking for
IUnknown
and the creation is successful. Then the exe asks for a different interface throughQueryInterface
and it fails withE_ACCESSDENIED
.If I launch the exe "as administrator" then the
QueryInterface
will return withS_OK
.I did not investigate further, I suspect there is some policy about the 32 bit - 64 bit interaction.