【问题标题】:Internet Explorer History countInternet Explorer 历史计数
【发布时间】:2012-02-21 00:17:09
【问题描述】:

如何获取 Internet Explorer 历史记录的计数?我可以在 vb 中使用 Shell.Application 来实现它,但在 delphi 中不能。 我发现了一个带有“CLSID_CUrlHistory”的代码,它显示了所有缓存条目。


我尝试转换相同,但我遗漏了一些东西,请查看以下答案并纠正我出错的地方

Procedure ListIeHistory;

Const
HISTORY_LIST = 34;
ITEM_NAME = 0;
ITEM_DATE = 2;

var
ShellSession        : OleVariant;
ShellHistory        : OleVariant;
ShellEntry          : OleVariant;
ShellHistoryFolder  : OleVariant;
ShellCollection     : OleVariant;
oEnum               : IEnumvariant;
iValue              : LongWord;

Begin
    result:='';
    ShellSession:= CreateOleObject('Shell.Application');
    ShellHistory    := ShellSession.Namespace(HISTORY_LIST);
    ShellHistoryFolder:= ShellHistory.self;
    ShellCollection  := ShellHistory.Items;
    oEnum         := IUnknown(ShellCollection._NewEnum) as IEnumVariant;

    while oEnum.Next(1, ShellEntry, iValue) = 0 do
        begin
                 form1.Memo1.Lines.Add(vartostr(ShellEntry.Name));
        end;
end;

由 TLama 编辑

请注意,此代码没有错误处理(我现在很忙),因此请以此为灵感。但是您确定这是您想要的吗?我想如果您按照我的答案中的代码并过滤一些项目(很可能是句号),您会得到相同的结果。

这浏览了C:\Users\TLama\AppData\Local\Microsoft\Windows\History 目录,所以我认为您缺少一些历史记录项(不是我;-),但我没有时间研究历史记录项的来源。

请注意,使用IUrlHistoryStg 接口是正确的方法,而不是这样

uses
  ComObj;

procedure TForm1.Button1Click(Sender: TObject);
var
  URL: string;
  Visited: string;
  I, J, K: Integer;
  Shell: OleVariant;
  Item: OleVariant;
  SiteFolder: OleVariant;
  SiteItem: OleVariant;
  PageFolder: OleVariant;
  PageItem: OleVariant;
  Folder: OleVariant;
const
  ITEM_NAME = 0;
  ITEM_DATE = 2;
  HISTORY_LIST = 34;
begin
  Shell := CreateOleObject('Shell.Application');
  Folder := Shell.NameSpace(HISTORY_LIST);
  Memo1.Lines.Add('Location: ' + Folder.Self.Path);

  for I := 0 to Folder.Items.Count - 1 do
  begin
    Item := Folder.Items.Item(I);
    Memo1.Lines.Add('Period: ' + Item.Name);

    if Item.IsFolder then
    begin
      SiteFolder := Item.GetFolder;
      for J := 0 to SiteFolder.Items.Count - 1 do
      begin
        SiteItem := SiteFolder.Items.Item(J);
        Memo1.Lines.Add('Site: ' + SiteItem.Name);

        if SiteItem.IsFolder then
        begin
          PageFolder := SiteItem.GetFolder;
          for K := 0 to PageFolder.Items.Count - 1 do
          begin
            PageItem := PageFolder.Items.Item(K);
            URL := PageFolder.GetDetailsOf(PageItem, ITEM_NAME);
            Visited := PageFolder.GetDetailsOf(PageItem, ITEM_DATE);
            Memo1.Lines.Add('URL: ' + URL + '; Visited: ' + Visited);
          end;
        end;
      end;
    end;
  end;
end;

【问题讨论】:

  • Embedded Web Browser Components Pack (aka TEmbeddedWB) 有一个 Url History 对象,您可以在其中查看和枚举 IE 历史列表。该组件与 Delphi5 到 XE 兼容。
  • 为什么要计数?这是一件复杂的事情。请解释您实际尝试做的事情,我也许可以建议正确的行动方案。
  • 您可以使用 IUrlHistoryStg::EnumUrls() 来枚举历史。 msdn.microsoft.com/en-us/library/ie/aa767720(v=vs.85).aspx
  • @jeffamaphone,它似乎返回与FindFirstUrlCacheEntryFindNextUrlCacheEntry 函数相同(或非常相似)的函数。我现在无法验证,但有时间我会检查一下。
  • 是的,确实如此。如果没有那就奇怪了。

标签: delphi internet-explorer browser-history


【解决方案1】:

完全重写基于jeffamaphone's 建议使用IUrlHistoryStg 接口。它似乎返回与此更新之前的代码相同或非常相似的结果(我没有验证)。

下面的代码应该将当前用户的 Internet Explorer 历史记录中的所有 URL 打印到备忘录框中,然后显示一个包含它们计数的消息框(很容易修改此代码以仅计算条目):

uses
  ComObj, ActiveX;

type
  TStatURL = record
    cbSize: DWORD;
    pwcsUrl: LPWSTR;
    pwcsTitle: LPWSTR;
    ftLastVisited: FILETIME;
    ftLastUpdated: FILETIME;
    ftExpires: FILETIME;
    dwFlags: DWORD;
  end;
  IEnumStatURL = interface(IUnknown)
    ['{3C374A42-BAE4-11CF-BF7D-00AA006946EE}']
    function Next(celt: ULONG; var elt: TStatURL; var pceltFetched: ULONG): HRESULT; stdcall;
    function Skip(celt: ULONG): HRESULT; stdcall;
    function Reset: HRESULT; stdcall;
    function Clone(out ppenum: IEnumStatURL): HRESULT; stdcall;
    function SetFilter(poszFilter: PWideChar; dwFlags: DWORD): HRESULT; stdcall;
  end;
  IUrlHistoryStg = interface(IUnknown)
    ['{3C374A41-BAE4-11CF-BF7D-00AA006946EE}']
    function AddUrl(pocsUrl: PWideChar; pocsTitle: PWideChar; dwFlags: DWORD): HRESULT; stdcall;
    function DeleteUrl(pocsUrl: PWideChar; dwFlags: DWORD): HRESULT; stdcall;
    function QueryUrl(pocsUrl: PWideChar; dwFlags: DWORD; var lpSTATURL: TStatURL): HRESULT; stdcall;
    function BindToObject(pocsUrl: PWideChar; var riid: TIID; out ppvOut: Pointer): HRESULT; stdcall;
    function EnumUrls(out ppenum: IEnumStatURL): HRESULT; stdcall;
  end;

const
  CLSID_CUrlHistory: TGUID = '{3C374A40-BAE4-11CF-BF7D-00AA006946EE}';

implementation

procedure TForm1.Button1Click(Sender: TObject);
var
  I: Cardinal;
  StatURL: TStatURL;
  EnumStatURL: IEnumStatURL;
  UrlHistoryStg: IUrlHistoryStg;
begin
  Memo1.Clear;
  Memo1.Lines.BeginUpdate;
  try
    UrlHistoryStg := CreateComObject(CLSID_CUrlHistory) as IUrlHistoryStg;
    if UrlHistoryStg.EnumUrls(EnumStatURL) = S_OK then
    begin
      while EnumStatURL.Next(1, StatURL, I) = S_OK do
      begin
        if I = 1 then
          Memo1.Lines.Add(StatURL.pwcsUrl);
      end;
    end;
  finally
    Memo1.Lines.EndUpdate;
  end;
  ShowMessage(IntToStr(Memo1.Lines.Count) + ' URLs found in history');
end;

有趣的是,没有人在IEnumSTATURL.Next方法的文档中提到你必须将celt参数值传递给1,否则你将陷入无限循环。

【讨论】:

  • 嗨 TLana,历史内容是 354,当(当我们点击查看历史时)我的 vb 输出给出的结果是准确的 354。但在 Delphi 中,显示所有条目以千为单位。在我的系统中,它显示的是 3164 而不是 354
  • 请查看上面的 vb 代码链接,它显示了确切的计数。帮我转换一下
猜你喜欢
  • 2011-08-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-03
  • 1970-01-01
  • 1970-01-01
  • 2010-10-09
  • 2011-01-02
相关资源
最近更新 更多