起因:接到开发任务,弄一个很简单的BHO,主要是记录IE的访问情况。
思路:建立基本的BHO框架、当用户访问页面变化时,将访问记录写入到SQLite数据库中。
开发环境:Win7+Delphi2010
问题:当写入数据库时,我用了网上较为常见的SQLiteDatabase(TSQLiteDataBase)。
结果编译后,如果包含初始化该对象的那条语句,整个BHO就失灵了,如果去掉就正常(当然,那样就没办法写入数据库了)代码片段:由于BHO代码比较常见,我就只写部分代码unit LookInBHO;{$WARN SYMBOL_PLATFORM OFF}
{$B-}
interfaceuses
  ComObj, ActiveX, LookInBHO_TLB, StdVcl, SHDOCVW, Registry, Windows, DateUtils,
  StrUtils, SysUtils, Dialogs, wininet, Classes, SQLiteTable3;type
  TLooKInBHO = class(TComObject,IDispatch,IObjectWithSite, ILooKInBHO)
  public
    function GetTypeInfoCount(out Count:Integer):HResult; stdcall;
    function GetTypeInfo(Index,LocaleID:Integer;out TypeInfo):HResult; stdcall;
    function GetIDsOfNames(const IID:TGUID;Names:Pointer;NameCount,LocaleID:Integer;DispIDs:Pointer):HResult; stdcall;
    function SetSite(const pUnkSite:IUnknown):HResult; stdcall;
    function GetSite(const riid:TIID;out site:IUnknown):HResult; stdcall;
    function Invoke(DispID:Integer;const IID:TGUID;LocaleID:Integer;Flags:Word;var Params;VarResult,ExcepInfo,ArgErr:Pointer):HResult; stdcall;
    procedure DoDocumentComplete(const pDisp: IDispatch; var URL: OleVariant);
    procedure DoOnQuit();
    procedure WriteDB();
    function getLastPos(const substr,s:string):integer;
    procedure DoBeforeNavigate2(const pDisp:IDispatch;var URL:OleVariant;var Flags:OleVariant;var
  TargetFrameName:OleVariant;var PostData:OleVariant;var Headers:OleVariant;var Cancel:WordBool);  private
    IEThis:IWebBrowser2;
    Cookie:Integer;
  end;
type  TLookinBHOFactory = class(TComObjectFactory)
  private
    procedure AddKeys;
    procedure RemoveKeys;
  public
    procedure UpdateRegistry(Register:Boolean); override;  end;implementationuses ComServ;var
  HasDb : boolean;
  iRnd : int64;
  sTime, eTime : TDatetime;
  vistacount : integer;
  sUrl,LastUrl : string;
/////////定义结束///////////////
//////////以下省去部分实现代码/////////
procedure TLooKInBHO.WriteDB;
var
  dbPath,sql : string;
  db : TSQLiteDatabase;
begin
  dbPath := 'D:\Project\Delphi\';{这个是测试用地址}
  if FileExists(dbPath + 'IEHistory.dat') then
  begin
    db := TSQLiteDatabase.Create(dbPath + 'IEHistory.dat');{就是这句,加上就无法正常使用,整个DLL就失灵了}
    try        sql := 'INSERT INTO ieUrl(id,rnd,url,v_time,c_time) VALUES (null,' + inttostr(iRnd) + ',"' + LeftStr(LastUrl,255) + '","' + FormatDateTime('yyyy-mm-dd hh:nn:ss',sTime) + '","' + FormatDateTime('yyyy-mm-dd hh:nn:ss',sTime) + '")';
        
      if db.TableExists('ieUrl') then begin
        db.ExecSQL(sql);
        db.Commit;
      end;
    except
      on E:Exception do
      MessageBox(0,Pwidechar(E.Message),'错误提示', MB_OK);    end;
    db.Destroy;
  end;
end;
//////////以上省去部分实现代码/////////
说实话,我不太懂Delphi,也刚刚开始搞BHO,所以希望各位大神多多帮忙。
个人分析,DLL失灵,测试中SetSite函数都无效,很有可能是接口实现出现问题。而代码中仅仅是加了一个类TSQLiteDataBase,那会不会是这个地方造成了接口实现出现了问题。
因为TSQLiteDataBase中引用了SQLite3(就是调用SQLite3.dll文件),会不会因为BHO再次调用DLL,因为操作系统权限的原因,导致调用失败,所以该BHO在初始化的时候失败。
如果需要更多信息,请回帖说明,多谢大家。

解决方案 »

  1.   

    BHO如何调试,求解。查了半年百度和谷歌都没有人知道。因为代码根本没有运行(感觉是接口就没有实现),所以调试什么的完全没有用。
      

  2.   

    对这个不熟。但提供下找错思路。如果不能在IDE里调试,就在你怀疑的地方放调试代码,输出日志到文件。从大范围慢慢往小范围缩。
      

  3.   

    BHO完全就没执行,主流调试方法基本无效,调试代码什么的根本没用。我只是想问问,接口中这样用类,会不会产生什么问题。
      

  4.   

    估计是bho的接口,对于调用外部dll有严格限制。
    试一试调用一个普通、简单的dll,会不会也如此
    否则,就是sqlite3.dll的特殊问题了
      

  5.   

    调用其他DLL,也会有特殊的函数不能用,估计是IE的BHO权限很低造成的。
    现在Windows的补丁越来越多,很多地方都会有权限问题,真是愁人啊,看来需要其他办法来解决了。