I have an app that requires FTDI D2XX Direct Drivers drivers to be installed in system. Now I am creating an installation script using Inno Setup. How can I get an information whether FTDI drivers are installed in system (Windows). Is there any path or registry entry that could be checked to gain unambiguous information about that?
1 Answers
There were two ways I was thinking of when posting this answer, but I've decided to show my preferred one that time. For the sake of completeness, I'm including also a generic way to check whether a library is present in the system.
1. Try to call an FTDI driver library function
I think the best you can do is trying to call a function from the driver's library itself using delayed loading (delayload
option). A good function to call is e.g. the FT_GetLibraryVersion
function, by which you can get the library version, and which does not require opened device. In the following example code is shown just how to test whether the library is present in the system:
[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;
It's just a probe if a library function can be called. Hence there is no result nor error checking.
2. Check the library presence in a generic way
Since the functions like LoadDLL
and FreeDLL
are deprecated (and there's no function to check if the library is already loaded), a generic way for checking whether a library is present in the system requires importing a few WinAPI functions. The following function LibraryExists
checks whether a library of a given name is already loaded by Inno Setup and if not, it tries to load and unload it:
[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;
And a possible usage for your case:
function IsFTD2xxInstalled: Boolean;
begin
Result := LibraryExists('ftd2xx.dll');
end;

- 75,147
- 17
- 214
- 392
-
Maybe the first check should be whether the .dll library is present in system. – Slappy Jan 09 '15 at 08:34
-
@Slappy, I was thinking of this. But I've decided to use this way since this verifies that a library named ftd2xx.dll is really a FTDI driver lib (or at least fakes it). And it shows that you can get a version of it which might be handy for someone. Finally, the `LoadDLL` function is deprecated hence this check would officially require importing WinAPI function (such as `LoadLibraryEx`). – TLama Jan 09 '15 at 08:49
-
@Slappy, for the sake of completness I've posted also the generic way. – TLama Jan 09 '15 at 10:52