如何从 Delphi 中的TEdgeBrowser/WebView 2访问CoreWebView 2CookieManager?

ih99xse1  于 2023-03-08  发布在  其他
关注(0)|答案(1)|浏览(1208)

我通过Delphi中的TEdgeBrowser使用微软的WebView2(目前是11.2,很快可能是11.3)。
我想删除一个特定的cookie。
原则上,使用CoreWebView2Cookie管理器的DeleteCookie方法,这是可能的,如这里的示例所解释的:https://stackoverflow.com/a/64293869/2776981
现在我的问题是:我怎样才能从Delphi访问它?

zwghvu4y

zwghvu4y1#

在安装了足够新的WebView2版本后,EdgeBrowser.ControllerInterface.Get_CoreWebView2()返回的ICoreWebView2还支持ICoreWebView2_2接口(接口ICoreWebView2的扩展),该接口具有Get_CookieManager方法,在此基础上,我提出了此解决方案。
DeleteAllCookies和DeleteCookies都可以工作(Emtpy字符串在DeleteCookies中用作域或路径的"通配符")。
主要的问题,如何从Delphi访问CoreWebView2CookieManager,似乎已经由此得到了答案。
这段代码中的接口声明是用tlibimp.exe创建的,如Stackoverflow这篇文章所述:WebView2 (TEdgeBrowser) updated Delphi interface (e.g. ICoreWebView2Controller2).

unit WebView2Cookies;

interface

uses
  Vcl.Edge;

procedure DeleteWebView2Cookies(EdgeBrowser: TCustomEdgeBrowser; const CookieName, CookieDomain, CookiePath: string);
procedure DeleteAllWebView2Cookies(EdgeBrowser: TCustomEdgeBrowser);

implementation

uses
  System.SysUtils,
  Winapi.ActiveX, Winapi.WebView2;

// Constants for enum COREWEBVIEW2_COOKIE_SAME_SITE_KIND
type
  COREWEBVIEW2_COOKIE_SAME_SITE_KIND = TOleEnum;
const
  COREWEBVIEW2_COOKIE_SAME_SITE_KIND_NONE = $00000000;
  COREWEBVIEW2_COOKIE_SAME_SITE_KIND_LAX = $00000001;
  COREWEBVIEW2_COOKIE_SAME_SITE_KIND_STRICT = $00000002;

const
  IID_ICoreWebView2_2: TGUID = '{9E8F0CF8-E670-4B5E-B2BC-73E061E3184C}';
  IID_ICoreWebView2CookieManager: TGUID = '{177CD9E7-B6F5-451A-94A0-5D7A3A4C4141}';

type
  ICoreWebView2_2 = interface;
  ICoreWebView2WebResourceResponseReceivedEventHandler = interface;
  ICoreWebView2DOMContentLoadedEventHandler = interface;
  ICoreWebView2WebResourceResponseReceivedEventArgs = interface;
  ICoreWebView2DOMContentLoadedEventArgs = interface;
  ICoreWebView2WebResourceResponseView = interface;
  ICoreWebView2WebResourceResponseViewGetContentCompletedHandler = interface;

  ICoreWebView2CookieManager = interface;
  ICoreWebView2Cookie = interface;
  ICoreWebView2GetCookiesCompletedHandler = interface;
  ICoreWebView2CookieList = interface;

// *********************************************************************//
// Interface: ICoreWebView2_2
// Flags:     (0)
// GUID:      {9E8F0CF8-E670-4B5E-B2BC-73E061E3184C}
// *********************************************************************//
  ICoreWebView2_2 = interface(ICoreWebView2)
    ['{9E8F0CF8-E670-4B5E-B2BC-73E061E3184C}']
    function add_WebResourceResponseReceived(const eventHandler: ICoreWebView2WebResourceResponseReceivedEventHandler;
                                             out token: EventRegistrationToken): HResult; stdcall;
    function remove_WebResourceResponseReceived(token: EventRegistrationToken): HResult; stdcall;
    function NavigateWithWebResourceRequest(const Request: ICoreWebView2WebResourceRequest): HResult; stdcall;
    function add_DOMContentLoaded(const eventHandler: ICoreWebView2DOMContentLoadedEventHandler;
                                  out token: EventRegistrationToken): HResult; stdcall;
    function remove_DOMContentLoaded(token: EventRegistrationToken): HResult; stdcall;
    function Get_CookieManager(out CookieManager: ICoreWebView2CookieManager): HResult; stdcall;
    function Get_Environment(out Environment: ICoreWebView2Environment): HResult; stdcall;
  end;

// *********************************************************************//
// Interface: ICoreWebView2WebResourceResponseReceivedEventHandler
// Flags:     (0)
// GUID:      {7DE9898A-24F5-40C3-A2DE-D4F458E69828}
// *********************************************************************//
  ICoreWebView2WebResourceResponseReceivedEventHandler = interface(IUnknown)
    ['{7DE9898A-24F5-40C3-A2DE-D4F458E69828}']
    function Invoke(const sender: ICoreWebView2;
                    const args: ICoreWebView2WebResourceResponseReceivedEventArgs): HResult; stdcall;
  end;

// *********************************************************************//
// Interface: ICoreWebView2DOMContentLoadedEventHandler
// Flags:     (0)
// GUID:      {4BAC7E9C-199E-49ED-87ED-249303ACF019}
// *********************************************************************//
  ICoreWebView2DOMContentLoadedEventHandler = interface(IUnknown)
    ['{4BAC7E9C-199E-49ED-87ED-249303ACF019}']
    function Invoke(const sender: ICoreWebView2; const args: ICoreWebView2DOMContentLoadedEventArgs): HResult; stdcall;
  end;

// *********************************************************************//
// Interface: ICoreWebView2WebResourceResponseReceivedEventArgs
// Flags:     (0)
// GUID:      {D1DB483D-6796-4B8B-80FC-13712BB716F4}
// *********************************************************************//
  ICoreWebView2WebResourceResponseReceivedEventArgs = interface(IUnknown)
    ['{D1DB483D-6796-4B8B-80FC-13712BB716F4}']
    function Get_Request(out Request: ICoreWebView2WebResourceRequest): HResult; stdcall;
    function Get_Response(out Response: ICoreWebView2WebResourceResponseView): HResult; stdcall;
  end;

// *********************************************************************//
// Interface: ICoreWebView2DOMContentLoadedEventArgs
// Flags:     (0)
// GUID:      {16B1E21A-C503-44F2-84C9-70ABA5031283}
// *********************************************************************//
  ICoreWebView2DOMContentLoadedEventArgs = interface(IUnknown)
    ['{16B1E21A-C503-44F2-84C9-70ABA5031283}']
    function Get_NavigationId(out NavigationId: Largeuint): HResult; stdcall;
  end;

// *********************************************************************//
// Interface: ICoreWebView2WebResourceResponseView
// Flags:     (0)
// GUID:      {79701053-7759-4162-8F7D-F1B3F084928D}
// *********************************************************************//
  ICoreWebView2WebResourceResponseView = interface(IUnknown)
    ['{79701053-7759-4162-8F7D-F1B3F084928D}']
    function Get_Headers(out Headers: ICoreWebView2HttpResponseHeaders): HResult; stdcall;
    function Get_StatusCode(out StatusCode: SYSINT): HResult; stdcall;
    function Get_ReasonPhrase(out ReasonPhrase: PWideChar): HResult; stdcall;
    function GetContent(const handler: ICoreWebView2WebResourceResponseViewGetContentCompletedHandler): HResult; stdcall;
  end;

// *********************************************************************//
// Interface: ICoreWebView2WebResourceResponseViewGetContentCompletedHandler
// Flags:     (0)
// GUID:      {875738E1-9FA2-40E3-8B74-2E8972DD6FE7}
// *********************************************************************//
  ICoreWebView2WebResourceResponseViewGetContentCompletedHandler = interface(IUnknown)
    ['{875738E1-9FA2-40E3-8B74-2E8972DD6FE7}']
    function Invoke(errorCode: HResult; const Content: IStream): HResult; stdcall;
  end;



  // *********************************************************************//
// Interface: ICoreWebView2CookieManager
// Flags:     (0)
// GUID:      {177CD9E7-B6F5-451A-94A0-5D7A3A4C4141}
// *********************************************************************//
  ICoreWebView2CookieManager = interface(IUnknown)
    ['{177CD9E7-B6F5-451A-94A0-5D7A3A4C4141}']
    function CreateCookie(name: PWideChar; value: PWideChar; Domain: PWideChar; Path: PWideChar;
                          out cookie: ICoreWebView2Cookie): HResult; stdcall;
    function CopyCookie(const cookieParam: ICoreWebView2Cookie; out cookie: ICoreWebView2Cookie): HResult; stdcall;
    function GetCookies(uri: PWideChar; const handler: ICoreWebView2GetCookiesCompletedHandler): HResult; stdcall;
    function AddOrUpdateCookie(const cookie: ICoreWebView2Cookie): HResult; stdcall;
    function DeleteCookie(const cookie: ICoreWebView2Cookie): HResult; stdcall;
    function DeleteCookies(name: PWideChar; uri: PWideChar): HResult; stdcall;
    function DeleteCookiesWithDomainAndPath(name: PWideChar; Domain: PWideChar; Path: PWideChar): HResult; stdcall;
    function DeleteAllCookies: HResult; stdcall;
  end;

// *********************************************************************//
// Interface: ICoreWebView2Cookie
// Flags:     (0)
// GUID:      {AD26D6BE-1486-43E6-BF87-A2034006CA21}
// *********************************************************************//
  ICoreWebView2Cookie = interface(IUnknown)
    ['{AD26D6BE-1486-43E6-BF87-A2034006CA21}']
    function Get_name(out name: PWideChar): HResult; stdcall;
    function Get_value(out value: PWideChar): HResult; stdcall;
    function Set_value(value: PWideChar): HResult; stdcall;
    function Get_Domain(out Domain: PWideChar): HResult; stdcall;
    function Get_Path(out Path: PWideChar): HResult; stdcall;
    function Get_Expires(out Expires: Double): HResult; stdcall;
    function Set_Expires(Expires: Double): HResult; stdcall;
    function Get_IsHttpOnly(out IsHttpOnly: Integer): HResult; stdcall;
    function Set_IsHttpOnly(IsHttpOnly: Integer): HResult; stdcall;
    function Get_SameSite(out SameSite: COREWEBVIEW2_COOKIE_SAME_SITE_KIND): HResult; stdcall;
    function Set_SameSite(SameSite: COREWEBVIEW2_COOKIE_SAME_SITE_KIND): HResult; stdcall;
    function Get_IsSecure(out IsSecure: Integer): HResult; stdcall;
    function Set_IsSecure(IsSecure: Integer): HResult; stdcall;
    function Get_IsSession(out IsSession: Integer): HResult; stdcall;
  end;

// *********************************************************************//
// Interface: ICoreWebView2GetCookiesCompletedHandler
// Flags:     (0)
// GUID:      {5A4F5069-5C15-47C3-8646-F4DE1C116670}
// *********************************************************************//
  ICoreWebView2GetCookiesCompletedHandler = interface(IUnknown)
    ['{5A4F5069-5C15-47C3-8646-F4DE1C116670}']
    function Invoke(result: HResult; const cookieList: ICoreWebView2CookieList): HResult; stdcall;
  end;

// *********************************************************************//
// Interface: ICoreWebView2CookieList
// Flags:     (0)
// GUID:      {F7F6F714-5D2A-43C6-9503-346ECE02D186}
// *********************************************************************//
  ICoreWebView2CookieList = interface(IUnknown)
    ['{F7F6F714-5D2A-43C6-9503-346ECE02D186}']
    function Get_Count(out Count: SYSUINT): HResult; stdcall;
    function GetValueAtIndex(index: SYSUINT; out cookie: ICoreWebView2Cookie): HResult; stdcall;
  end;


procedure GetCookieManager(EdgeBrowser: TCustomEdgeBrowser; out CookieManager: ICoreWebView2CookieManager);
var
  Core2: ICoreWebView2;
  Core2_2: ICoreWebView2_2;
  HR: HRESULT;
begin
  EdgeBrowser.ControllerInterface.Get_CoreWebView2(Core2);
  if not Assigned(Core2) then
    raise Exception.Create('Get_CoreWebView2 not found');

  Core2.QueryInterface(IID_ICoreWebView2_2, Core2_2);
  if not Assigned(Core2_2) then
    raise Exception.Create('IID_ICoreWebView2_2 not found');

  HR := Core2_2.Get_CookieManager(CookieManager);
  if not Succeeded(HR) then
    raise Exception.Create('Get_CookieManager failed');
end;

procedure DeleteWebView2Cookies(EdgeBrowser: TCustomEdgeBrowser; const CookieName, CookieDomain, CookiePath: string);
var
  CookieMan: ICoreWebView2CookieManager;
  HR: HRESULT;
begin
  GetCookieManager(EdgeBrowser, CookieMan);
  HR := CookieMan.DeleteCookiesWithDomainAndPath(PWideChar(CookieName), PWideChar(CookieDomain), PWideChar(CookiePath));
  if not Succeeded(HR) then
    raise Exception.Create('DeleteCookiesWithDomainAndPath failed');
end;

procedure DeleteAllWebView2Cookies(EdgeBrowser: TCustomEdgeBrowser);
var
  CookieMan: ICoreWebView2CookieManager;
  HR: HRESULT;
begin
  GetCookieManager(EdgeBrowser, CookieMan);
  HR := CookieMan.DeleteAllCookies;
  if not Succeeded(HR) then
    raise Exception.Create('DeleteAllCookies failed');
end;

end.

以下ShowWebView2Cookies过程可能也有助于试验界面和研究Cookie:
使用Vcl.对话框;

type
  TCompletedHandler = class(TInterfacedObject, ICoreWebView2GetCookiesCompletedHandler)
  private
    function Invoke(CallResult: HResult; const cookieList: ICoreWebView2CookieList): HResult; stdcall;
  end;

procedure ShowWebView2Cookies(EdgeBrowser: TCustomEdgeBrowser);
var
  CookieMan: ICoreWebView2CookieManager;
  CompletedHandler: ICoreWebView2GetCookiesCompletedHandler;
begin
  GetCookieManager(EdgeBrowser, CookieMan);
  CompletedHandler := TCompletedHandler.Create;
  CookieMan.GetCookies('', CompletedHandler);
end;

{ TCompletedHandler }

function TCompletedHandler.Invoke(CallResult: HResult;
  const cookieList: ICoreWebView2CookieList): HResult;
var
  s: string;
  i, Count: SYSUINT;
  LCookie: ICoreWebView2Cookie;
  HR: HResult;
  pwc: PWideChar;
begin
  if not Succeeded(CallResult) then
    raise Exception.Create('GetCookies failed');

  HR := cookieList.Get_Count(Count);
  if not Succeeded(HR) then
    raise Exception.Create('cookieList.Get_Count failed');

  s := 'Found ' + IntToStr(Count) + ' cookies:' + #13#10;
  if Count > 0 then
  begin
    for i := 0 to Count - 1 do
    begin
      HR := cookieList.GetValueAtIndex(i, LCookie);
      if not Succeeded(HR) then
        raise Exception.Create('cookieList.GetValueAtIndex failed');

      LCookie.Get_name(pwc);
      s := s + 'name = ' + pwc;
      CoTaskMemFree(pwc);

      LCookie.Get_Domain(pwc);
      s := s + ', domain = ' + pwc;
      CoTaskMemFree(pwc);

      LCookie.Get_Path(pwc);
      s := s + ', path = ' + pwc;
      CoTaskMemFree(pwc);

      s := s + #13#10;

    end;
  end;
  ShowMessage(s);

  Result := S_OK;
end;

相关问题