简体   繁体   English

为什么在使用TEmbeddedWB时QueryService不被IHttpSecurity调用?

[英]Why doesn't QueryService get called for IHttpSecurity when using TEmbeddedWB?

TEmbeddedWB contains an event for extending support for additional services, called OnQueryService . TEmbeddedWB包含一个事件,用于扩展对其他服务的支持,称为OnQueryService According to MSDN , this function will be called to allow me to return an IHttpSecurity reference, so I can handle certificate errors my way. 根据MSDN ,将调用此函数以允许我返回IHttpSecurity引用,因此我可以用自己的方式处理证书错误。 However, while OnQueryService is called for a number of other interfaces, it never gets called for IHttpSecurity . 然而,虽然OnQueryService被调用一些其他的接口,它永远不会被调用的IHttpSecurity

Sample code: 样例代码:

unit InsecureBrowser;

interface

uses
  Winapi.Windows,
  Winapi.Messages,
  Winapi.Urlmon,
  Winapi.WinInet,
  System.SysUtils,
  System.Variants,
  System.Classes,
  Vcl.Graphics,
  Vcl.Controls,
  Vcl.Forms,
  Vcl.Dialogs,
  Vcl.OleCtrls,
  Vcl.StdCtrls,
  SHDocVw_EWB,
  EwbCore,
  EmbeddedWB;

type
  TInsecureBrowserForm = class(TForm, IHttpSecurity, IWindowForBindingUI)
    web: TEmbeddedWB;
    cmdGoInsecure: TButton;
    procedure webQueryService(Sender: TObject; const [Ref] rsid,
      iid: TGUID; var Obj: IInterface);
    procedure cmdGoInsecureClick(Sender: TObject);
  private
    { IWindowForBindingUI }
    function GetWindow(const guidReason: TGUID; out hwnd): HRESULT; stdcall;

    { IHttpSecurity }
    function OnSecurityProblem(dwProblem: Cardinal): HRESULT; stdcall;
  end;

var
  InsecureBrowserForm: TInsecureBrowserForm;

implementation

{$R *.dfm}

function TInsecureBrowserForm.GetWindow(const guidReason: TGUID;
  out hwnd): HRESULT;
begin
  Result := S_FALSE;
end;

function TInsecureBrowserForm.OnSecurityProblem(dwProblem: Cardinal): HRESULT;
begin
  if (dwProblem = ERROR_INTERNET_INVALID_CA) or
     (dwProblem = ERROR_INTERNET_SEC_CERT_CN_INVALID)
    then Result := S_OK
    else Result := E_ABORT;
end;

procedure TInsecureBrowserForm.webQueryService(Sender: TObject;
  const [Ref] rsid, iid: TGUID; var Obj: IInterface);
begin
  if IsEqualGUID(IID_IWindowForBindingUI, iid) then
    Obj := Self as IWindowForBindingUI
  else if IsEqualGUID(IID_IHttpSecurity, iid) then
    Obj := Self as IHttpSecurity;
end;

procedure TInsecureBrowserForm.cmdGoInsecureClick(Sender: TObject);
begin
  web.Navigate('https://evil.intranet.site');
end;

end.

It's not obvious, but it turns out you need to navigate to about:blank before using WebBrowser2 , or certain things just don't happen, including some QueryService calls. 这不是很明显,但是事实证明,在使用WebBrowser2之前,您需要导航到about:blank ,否则某些事情就不会发生,包括一些QueryService调用。 Thanks to Igor Tandetnik for identifying this in 2010 . 感谢Igor Tandetnik 在2010年确定了这一点。

So, just add: 因此,只需添加:

procedure TInsecureBrowserForm.FormCreate(Sender: TObject);
begin
  web.Navigate('about:blank');
end;

I also wrote this up on my blog: https://marc.durdin.net/2016/03/dont-forget-to-navigate-to-aboutblank-when-embedding-iwebbrowser2/ 我也在我的博客上写了这个: https : //marc.durdin.net/2016/03/dont-forget-to-navigate-to-aboutblank-when-embedding-iwebbrowser2/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM