我有一个应用程序需要在系统中安装 FTDI D2XX Direct Drivers 驱动程序。现在我正在使用 Inno Setup 创建安装脚本。如何获取系统 (Windows) 中是否安装了 FTDI 驱动程序的信息。是否有任何路径或注册表项可以检查以获取有关它的明确信息?
最佳答案
发布此答案时,我想到了两种方式,但当时我决定展示我最喜欢的一种方式。为了完整起见,我还包括了一种检查系统中是否存在库的通用方法。
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. 以通用方式检查库的存在
由于像
LoadDLL
这样的功能和 FreeDLL
已弃用(并且没有函数来检查库是否已加载),检查系统中是否存在库的通用方法需要导入一些 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;
关于registry - 如何检测系统中的FTDI驱动程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27837561/