【问题标题】:How to detect FTDI driver in system如何检测系统中的 FTDI 驱动程序
【发布时间】:2015-03-06 09:59:29
【问题描述】:

我有一个需要在系统中安装 FTDI D2XX Direct Drivers 驱动程序的应用程序。现在我正在使用 Inno Setup 创建一个安装脚本。如何获取系统 (Windows) 中是否安装了 FTDI 驱动程序的信息。是否有任何路径或注册表项可以被检查以获得明确的信息?

【问题讨论】:

    标签: registry inno-setup drivers ftdi


    【解决方案1】:

    发布此答案时,我想到了两种方法,但我决定在那时展示我更喜欢的一种。为了完整起见,我还包括了一种检查系统中是否存在库的通用方法。

    1。尝试调用 FTDI 驱动程序库函数

    我认为您能做的最好的事情是尝试使用延迟加载(delayload 选项)从驱动程序库本身调用一个函数。一个好的调用函数是例如FT_GetLibraryVersion函数,通过该函数可以获取库版本,不需要打开设备。下面的示例代码展示了如何测试系统中是否存在该库:

    [Code]
    type
      ULONG = Cardinal;
      FT_STATUS = ULONG;
    
    function FT_GetLibraryVersion(out lpdwVersion: DWORD): FT_STATUS;
      external 'FT_GetLibraryVersion@ftd2xx.dll stdcall delayload';
    
    function IsFTD2xxInstalled: Boolean;
    var
      Version: DWORD;
    begin
      Result := True;
      try
        FT_GetLibraryVersion(Version);
      except
        Result := False;
      end;
    end;
    

    是否可以调用库函数只是一个探测。因此没有结果也没有错误检查。

    2。以通用方式检查库的存在

    由于 LoadDLLFreeDLL 之类的函数已被弃用(并且没有检查库是否已加载的函数),因此检查系统中是否存在库的通用方法需要导入一些 WinAPI 函数.下面的函数LibraryExists 检查给定名称的库是否已经被 Inno Setup 加载,如果没有,它会尝试加载和卸载它:

    [Code]
    #ifdef UNICODE
      #define AW "W"
    #else
      #define AW "A"
    #endif
    
    const
      ERROR_MOD_NOT_FOUND = 126;
    
    type
      HINSTANCE = THandle;
      HMODULE = HINSTANCE;
    
    function LoadLibrary(lpLibFileName: string): HMODULE;
      external 'LoadLibrary{#AW}@kernel32.dll stdcall';
    function FreeLibrary(hLibModule: HMODULE): BOOL;
      external 'FreeLibrary@kernel32.dll stdcall';
    function GetModuleHandle(lpModuleName: string): HMODULE;
      external 'GetModuleHandle{#AW}@kernel32.dll stdcall';
    
    procedure RaiseLastError(const Message: string; const Exclude: array of LongInt);
    var
      I: Integer;
      LastError: LongInt;
    begin
      LastError := DLLGetLastError;
      for I := 0 to GetArrayLength(Exclude) - 1 do
        if Exclude[I] = LastError then
          Exit;
      RaiseException(Format('%s' + #13#10 + '%d: %s', [Message, LastError,
        SysErrorMessage(LastError)]));
    end;
    
    function IsModuleLoaded(const Name: string): Boolean;
    begin
      Result := GetModuleHandle(Name) <> 0;
      if not Result then
        RaiseLastError('GetModuleHandle call failed.', [ERROR_MOD_NOT_FOUND]);
    end;
    
    function LibraryExists(const Name: string): Boolean;
    var
      Handle: HMODULE;
    begin
      Result := IsModuleLoaded(Name);
      if not Result then
      begin
        Handle := LoadLibrary(Name);
        if Handle <> 0 then
        begin
          Result := True;
          FreeLibrary(Handle);
        end
        else
          RaiseLastError('LoadLibrary call failed.', [ERROR_MOD_NOT_FOUND]);
      end;
    end;
    

    您的情况可能的用法:

    function IsFTD2xxInstalled: Boolean;
    begin
      Result := LibraryExists('ftd2xx.dll');
    end;
    

    【讨论】:

    • 也许第一个检查应该是系统中是否存在 .dll 库。
    • @Slappy,我在想这个。但我决定使用这种方式,因为这可以验证名为 ftd2xx.dll 的库确实是 FTDI 驱动程序库(或者至少是伪造的)。它表明你可以获得它的一个版本,它可能对某人很方便。最后,LoadDLL 函数已被弃用,因此此检查将正式要求导入 WinAPI 函数(例如 LoadLibraryEx)。
    • @Slappy,为了完整起见,我也发布了通用方式。
    猜你喜欢
    • 2011-04-24
    • 2014-10-12
    • 1970-01-01
    • 1970-01-01
    • 2020-09-27
    • 2010-09-11
    • 1970-01-01
    • 1970-01-01
    • 2013-07-10
    相关资源
    最近更新 更多