0

我在我的应用程序中使用 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;
    }
};
4

2 回答 2

1

我猜您在一个线程中创建了浏览器并将其传递给另一个线程。
如果是这种情况,您应该这样做:

在将IWebBrowser2实例传递给另一个线程之前,在创建线程中调用CoMarshalInterThreadInterfaceInStream,这会将其编组(转换)为线程安全IStream对象,然后才将其传递给 tagert 线程。
稍后,在目标线程中,您应该CoGetInterfaceAndReleaseStream使用先前编组的IStream实例进行调用,这会将其解组回目标线程中的原始对象(并IStream沿途释放对象)。

MSDN 中的CoMarshalInterThreadInterfaceInStream MSDN 中的
CoGetInterfaceAndReleaseStream

希望有帮助。

于 2011-07-14T12:02:37.910 回答
1

好吧,我终于有时间回到这个了..

事实证明,如果您在页面完全加载之前调用 get_Document 会失败,但返回值 (S_FALSE) 表示完全不同的错误(“脚本不安全”)

顺便说一句,加载本地页面将为您提供理想的行为。

因此,在页面加载后调用 get_Document(DISPID_NAVIGATECOMPLETE2、DISPID_DOWNLOADCOMPLETE、DISPID_DOCUMENTCOMPLETE)就可以了。

希望这可以帮助。

于 2011-09-22T08:31:14.890 回答