使 IWebBrowser2 Control 能够安全地编写脚本
我在应用程序中使用 IWebBrowser2 控件来显示外部网页。 问题是该对象对于脚本编写来说不安全,并且对 get_Document 的调用失败(以 S_FALSE 作为返回值)。
我实现了一个新类 IScriptableWebBrowser2,它继承自 IWebBrowser2 和 IWebBrowser2。 IObjectSafety,并尝试使用它代替 IWebBrowser2,但这并没有成功。
如何使 IWebBrowser2 控件能够安全地编写脚本?
class IScriptableWebBrowser2 :
public CComObjectRootEx<CComSingleThreadModel>,
public IWebBrowser2,
public IObjectSafety
{
BEGIN_COM_MAP(IScriptableWebBrowser2)
COM_INTERFACE_ENTRY(IObjectSafety)
END_COM_MAP()
// IObjectSafety implementation
STDMETHODIMP GetInterfaceSafetyOptions(REFIID riid,
DWORD *pdwSupportedOptions,
DWORD *pdwEnabledOptions )
{
*pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER |
INTERFACESAFE_FOR_UNTRUSTED_DATA;
*pdwEnabledOptions = *pdwSupportedOptions;
return S_OK;
}
STDMETHODIMP SetInterfaceSafetyOptions(REFIID riid, DWORD dwOptionSetMask, DWORD dwEnabledOptions)
{
return S_OK;
}
};
I'm using IWebBrowser2 control in my application to display external web pages.
The problem is that the object is not safe for scripting and calls to get_Document fails (with S_FALSE as return value).
I've implemented a new class, IScriptableWebBrowser2 that inherits both from IWebBrowser2 & IObjectSafety, and tried to use it instead of IWebBrowser2 but that didn't do the trick.
How do I make my IWebBrowser2 control safe for scripting ?
class IScriptableWebBrowser2 :
public CComObjectRootEx<CComSingleThreadModel>,
public IWebBrowser2,
public IObjectSafety
{
BEGIN_COM_MAP(IScriptableWebBrowser2)
COM_INTERFACE_ENTRY(IObjectSafety)
END_COM_MAP()
// IObjectSafety implementation
STDMETHODIMP GetInterfaceSafetyOptions(REFIID riid,
DWORD *pdwSupportedOptions,
DWORD *pdwEnabledOptions )
{
*pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER |
INTERFACESAFE_FOR_UNTRUSTED_DATA;
*pdwEnabledOptions = *pdwSupportedOptions;
return S_OK;
}
STDMETHODIMP SetInterfaceSafetyOptions(REFIID riid, DWORD dwOptionSetMask, DWORD dwEnabledOptions)
{
return S_OK;
}
};
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我猜您在一个线程中创建了浏览器并将其传递给另一个线程。
如果是这种情况,您应该执行以下操作:
在将
IWebBrowser2
实例传递给另一个线程之前,在创建线程中,调用CoMarshalInterThreadInterfaceInStream
,这会将其编组(转换)为线程安全的IStream
对象,然后才将其传递给 tagert 线程。稍后,在目标线程中,您应该使用先前封送的
IStream
实例调用CoGetInterfaceAndReleaseStream
,这会将其解封回目标线程中的原始对象(并释放 < code>IStream 对象)。MSDN 中的 CoMarshalInterThreadInterfaceInStream
MSDN 中的 CoGetInterfaceAndReleaseStream
希望有所帮助。
I guess you created the browser in a thread and passed it on to another thread.
If that's the case, here's what you should do:
Before passing the
IWebBrowser2
instance to another thread, in the creating thread, callCoMarshalInterThreadInterfaceInStream
, that will marshal (convert) it to a thread-safeIStream
object, and only then pass it to the tagert thread.Later, in the target thread, you should call
CoGetInterfaceAndReleaseStream
with the previously marshaledIStream
instance, which will unmarshal it back to your original object in the target thread (and release theIStream
object along the way).CoMarshalInterThreadInterfaceInStream in MSDN
CoGetInterfaceAndReleaseStream in MSDN
Hope that helps.
好吧,我终于有时间回到这个问题了。
事实证明,如果您在页面完全加载之前调用 get_Document 则会失败,但返回值 (S_FALSE) 指示完全不同的错误(“脚本编写不安全”)
顺便说一句,加载本地页面将为您提供理想的行为。
因此,在页面加载后调用 get_Document(DISPID_NAVIGATECOMPLETE2、DISPID_DOWNLOADCOMPLETE、DISPID_DOCUMENTCOMPLETE)即可解决问题。
希望这有帮助。
Well, I finally had some time to come back to this one..
It turns out that get_Document fails if you call it BEFORE the page completely loaded but the return value (S_FALSE) indicates a completely different error ("not safe for scripting")
btw, Loading local pages will give you the desirable behavior.
Therefore, calling get_Document after the page was loaded (DISPID_NAVIGATECOMPLETE2, DISPID_DOWNLOADCOMPLETE, DISPID_DOCUMENTCOMPLETE) will do the trick.
Hope this helps.