我在应用程序中使用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;
}
};发布于 2011-09-22 16:31:15
好吧,我终于有时间回到这个问题上来了..
事实证明,如果您在页面完全加载之前调用get_Document,但返回值(S_FALSE)指示一个完全不同的错误(“对脚本不安全”),那么它就会失败。
顺便说一句,加载本地页面会给你带来想要的行为。
因此,在页面加载后调用get_Document (DISPID_NAVIGATECOMPLETE2、DISPID_DOWNLOADCOMPLETE、DISPID_DOCUMENTCOMPLETE)就可以了。
希望这能有所帮助。
发布于 2011-07-14 20:02:38
我猜你在一个线程中创建了浏览器,并将其传递给了另一个线程。
如果是这种情况,下面是你应该做的:
在将IWebBrowser2实例传递给另一个线程之前,在创建线程中调用CoMarshalInterThreadInterfaceInStream,后者会将其编组(转换)为线程安全的IStream对象,然后才将其传递给标记线程。
稍后,在目标线程中,您应该使用先前编组的IStream实例调用CoGetInterfaceAndReleaseStream,这将把它解组回目标线程中的原始对象(并在此过程中释放IStream对象)。
CoMarshalInterThreadInterfaceInStream in MSDN
CoGetInterfaceAndReleaseStream in MSDN
希望这能有所帮助。
https://stackoverflow.com/questions/6568811
复制相似问题