我在我的应用程序中使用IWebBrowser2控件来显示外部网页。 问题是该对象对于脚本编写是不安全的,并且对get_Document的调用失败(使用S_FALSE作为返回值)。
我已经实现了一个新的类,IScriptableWebBrowser2,它继承了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;
}
};
答案 0 :(得分:1)
我猜你是在一个线程中创建了浏览器并将其传递给另一个线程 如果是这样的话,这就是你应该做的:
在将IWebBrowser2
实例传递给另一个线程之前,在创建线程中,调用CoMarshalInterThreadInterfaceInStream
,将其编组(转换)为线程安全的IStream
对象,然后才将它传递给tagert线程
稍后,在目标线程中,您应该使用先前封送的CoGetInterfaceAndReleaseStream
实例调用IStream
,该实例将其解组回目标线程中的原始对象(并释放IStream
对象方式)。
CoMarshalInterThreadInterfaceInStream in MSDN
CoGetInterfaceAndReleaseStream in MSDN
希望有所帮助。
答案 1 :(得分:1)
好吧,我终于有时间回到这个......
事实证明,如果在页面完全加载之前调用它,则get_Document会失败,但返回值(S_FALSE)表示完全不同的错误(“不安全的脚本”)
顺便说一句,加载本地页面会给你理想的行为。
因此,在加载页面后调用get_Document(DISPID_NAVIGATECOMPLETE2,DISPID_DOWNLOADCOMPLETE,DISPID_DOCUMENTCOMPLETE)就可以了。
希望这有帮助。