Как определить версию используемой DLL программно?

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

jsa
постоялец
Сообщения: 295
Зарегистрирован: 28.11.2017 12:46:04

Как определить версию используемой DLL программно?

Сообщение jsa »

Здравствуйте.
За годы на компе бардачок накопился.
dblib.dll для компоненты TMSSQLConnection лежат 3х версий 0.95, 1.0, 1.3
Что-то в папках по проектам, что-то в IDE что-то в системных папках ОС Windows
Отсюда вопрос возник, какой именно файл dll использует программа, если явно его нигде не указывать.
Можно ли программно определить какой файл подцепляется при запуске, и его версию?
Аватара пользователя
Alexx2000
постоялец
Сообщения: 490
Зарегистрирован: 25.10.2006 00:22:07
Откуда: Мытищи
Контактная информация:

Сообщение Alexx2000 »

Код: Выделить всё

program project1;

{$mode objfpc}{$H+}

uses
  Classes, SysUtils, Windows, FileInfo;

var
  h: TLibHandle;
  ModuleName: UnicodeString;
begin
  h:= LoadLibrary('uxtheme.dll');
  {
    либо
    h:= GetModuleHandle('uxtheme.dll');
    если библиотека уже загружена.
  }

  if (h <> NilHandle) then
  begin
    SetLength(ModuleName, MAX_PATH + 1);
    SetLength(ModuleName, GetModuleFileNameW(h, PWideChar(ModuleName), MAX_PATH));
    WriteLn(ModuleName);

    with TVersionInfo.Create do
    begin
      Load(h);

      WriteLn(Format('%d.%d.%.d', [FixedInfo.FileVersion[0],
                                       FixedInfo.FileVersion[1],
                                       FixedInfo.FileVersion[2]]));

      Free;
    end;
  end;

  ReadLn;
end.
jsa
постоялец
Сообщения: 295
Зарегистрирован: 28.11.2017 12:46:04

Сообщение jsa »

Спасибо.
Это ответ на второй вопрос, про определение версии известного файла.
А как определить какой именно (по какому пути) файл используется?
Аватара пользователя
Alexx2000
постоялец
Сообщения: 490
Зарегистрирован: 25.10.2006 00:22:07
Откуда: Мытищи
Контактная информация:

Сообщение Alexx2000 »

Это ответ на оба вопроса, вот часть кода которая выводит путь

Код: Выделить всё

    SetLength(ModuleName, MAX_PATH + 1);
    SetLength(ModuleName, GetModuleFileNameW(h, PWideChar(ModuleName), MAX_PATH));
    WriteLn(ModuleName);
Аватара пользователя
Снег Север
долгожитель
Сообщения: 3067
Зарегистрирован: 27.11.2007 15:14:47
Контактная информация:

Сообщение Снег Север »

Windows всегда использует в первую очередь ту длл, которая лежит в одной папке с экзешником, потом ту, что указана в переменной окружения PATH, потом ту, что найдет в системных папках. Исключений не бывает, это не линух.
xchgeaxeax
постоялец
Сообщения: 198
Зарегистрирован: 11.05.2023 02:51:40

Сообщение xchgeaxeax »

Снег Север писал(а):потом ту, что найдет в системных папках
Там искать не будет, если они не перечислены в PATH - это не linux, где нету столько разбросанного по разным папкам бинарного мусора.
Аватара пользователя
Vapaamies
постоялец
Сообщения: 292
Зарегистрирован: 24.07.2012 22:37:59
Откуда: Санкт-Петербург
Контактная информация:

Сообщение Vapaamies »

Из командной строки — есть команда where (оказалось даже, что она встроена в cmd.exe, отдельного файла where.exe я не нашел). Для более глубокого погружения — Process Explorer Русиновича, он не только DLL покажет.
Аватара пользователя
Снег Север
долгожитель
Сообщения: 3067
Зарегистрирован: 27.11.2007 15:14:47
Контактная информация:

Сообщение Снег Север »

xchgeaxeax писал(а):Там искать не будет, если они не перечислены в PATH
Бред. Бинарный мусор где попало - это фишка линухов, причем у всех мусор лежит по-разному.
Alex2013
долгожитель
Сообщения: 3211
Зарегистрирован: 03.04.2013 11:59:44

Сообщение Alex2013 »

Насколько я помню dll могут каким то образом регистрироваться в системе ( скорее всего в реестре)
Зы
https://remontka.pro/dll-register-windows/
https://lumpics.ru/how-register-dll-library-in-system/
xchgeaxeax
постоялец
Сообщения: 198
Зарегистрирован: 11.05.2023 02:51:40

Сообщение xchgeaxeax »

Специально ради проверки поставил на VirtualBox чистую Windows. Как и ожидалось в ней куча допотопных костылей. На чистой Windows в PATH перечислены %SystemRoot% и %SystemRoot%system32, хотя судя по алгоритму поиска это избыточно для библиотек (т.е. поиск по этим каталогам будет выполняться дважды). Но подозреваю, что научить cmd.exe этим же фокусам они так и не догадались, поэтому в PATH до сих пор болтаются эти каталоги.

Добавлено спустя 2 минуты 3 секунды:
Alex2013 писал(а):Насколько я помню dll могут каким то образом регистрироваться в системе ( скорее всего в реестре)
По предыдущей ссылке как раз показан пункт 5 - Known DLLs. Это как раз и подразумевает поиск в списке "установленных в систему". Попытка сделать каталог /lib и /lib64 из linux.
jsa
постоялец
Сообщения: 295
Зарегистрирован: 28.11.2017 12:46:04

Сообщение jsa »

Всем спасибо.
Аватара пользователя
Vapaamies
постоялец
Сообщения: 292
Зарегистрирован: 24.07.2012 22:37:59
Откуда: Санкт-Петербург
Контактная информация:

Сообщение Vapaamies »

xchgeaxeax писал(а):по алгоритму поиска это избыточно для библиотек (т.е. поиск по этим каталогам будет выполняться дважды).
А посмотреть?

Код: Выделить всё

echo "%SystemRoot%"  "%SystemRoot%\system32"
"C:\Windows"  "C:\Windows\system32"
xchgeaxeax
постоялец
Сообщения: 198
Зарегистрирован: 11.05.2023 02:51:40

Сообщение xchgeaxeax »

Vapaamies писал(а):А посмотреть?

Код: Выделить всё

program Project1;

uses
  Windows, SysUtils;

var
  S: UnicodeString;

begin
  SetLength(S, MAX_PATH + 1);
  SetLength(S, GetWindowsDirectoryW(PWideChar(S), MAX_PATH));
  WriteLn('GetWindowsDirectoryW = "', S, '"'); // GetWindowsDirectoryW
  WriteLn('echo %SystemRoot%    = "', GetEnvironmentVariable('SystemRoot'), '"'); // %SystemRoot%
  WriteLn;
  SetLength(S, MAX_PATH + 1);
  SetLength(S, GetSystemDirectoryW(PWideChar(S), MAX_PATH));
  WriteLn('GetSystemDirectoryW        = "', S, '"');
  WriteLn('echo %SystemRoot%\system32 = "', GetEnvironmentVariable('SystemRoot'), '\system32"'); // %SystemRoot%\system32
  WriteLn;
  ReadLn;
end.
Посмотрел:
Screenshot_20240112_203949.png
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Аватара пользователя
Vapaamies
постоялец
Сообщения: 292
Зарегистрирован: 24.07.2012 22:37:59
Откуда: Санкт-Петербург
Контактная информация:

Сообщение Vapaamies »

xchgeaxeax писал(а):

Код: Выделить всё

  WriteLn('GetWindowsDirectoryW = "', S, '"'); // GetWindowsDirectoryW
[...]
  WriteLn('GetSystemDirectoryW        = "', S, '"');
end.
И?
Ответить