Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Получить специфическую для DLL информацию о версии

Delphi , Файловая система , DLL и PlugIns

Получить специфическую для DLL информацию о версии

Оформил: DeeCo
Автор: http://www.swissdelphicenter.ch

{*************************** 
** DllGetVersion Function ** 

***************************}

 { 
  Implemented by many of the Microsoft® Windows® Shell dynamic-link libraries (DLLs) to 
  allow applications to obtain DLL-specific version information. 
}


 { 
  Using DllGetVersion to Determine the Version Number 
  Starting with version 4.71, the Shell and common controls DLLs, among others, 
  began exporting DllGetVersion. 
  This function can be called by an application to determine which DLL 
  version is present on the system. It returns a structure that contains version information. 

  Note  DLLs do not necessarily export DllGetVersion. Always test for it 
  before attempting to use it. 
  For systems earlier than Windows 2000, DllGetVersion returns a DLLVERSIONINFO structure 
  that contains the major and minor version numbers, the build number, 
  and a platform identifier (ID). 
  For Windows 2000 and later systems, DllGetVersion might instead return a 
  DLLVERSIONINFO2 structure. This structure contains the QFE number that identifies 
  the service pack and provides a more robust way to compare version numbers than DLLVERSIONINFO. 
  Because the first member of DLLVERSIONINFO2 is a DLLVERSIONINFO structure, 
  the new structure is backward-compatible. 
}

 // DLLVERSIONINFO structure 
type
   PDLLVerInfo=^TDLLVersionInfo;
   TDLLVersionInfo=Record
     cbSize,   // Size of the structure, in bytes. 
    dwMajorVersion, // Major version of the DLL 
    dwMinorVersion, // Minor version of the DLL 
    dwBuildNumber, // Build number of the DLL 
    dwPlatformID: DWord; // Identifies the platform for which the DLL was built 
end;

 var
   DllGetVersion: function(dvi: PDLLVerInfo): PDLLVerInfo; stdcall;

 function GetDllVersion(DllName: string; var DLLVersionInfo: TDLLVersionInfo): Boolean;
 var
   hInstDll: THandle;
   p: pDLLVerInfo;
 begin
   Result := False;
   // Get a handle to the DLL module. 
  // das Handle zum DLL Modul ermitteln. 
  hInstDll := LoadLibrary(PChar(DllName));
   if (hInstDll = 0) then Exit;
   // Return the address of the specified exported (DLL) function. 
  // Adresse der Dll-Funktion ermitteln 
  @DllGetVersion := GetProcAddress(hInstDll, 'DllGetVersion');
   // If the handle is not valid, clean up an exit. 
  // Wenn das Handle ungьltig ist, wird die Funktion verlassen 
  if (@DllGetVersion) = nil then
   begin
     FreeLibrary(hInstDll);
     Exit;
   end;

   new(p);
   try
     ZeroMemory(p, SizeOf(p^));
     p^.cbSize := SizeOf(p^);

     // Call the DllGetVersion function 
    // Die DllGetVersion() Funktion aufrufen 
    DllGetVersion(p);
     DLLVersionInfo.dwMajorVersion := p^.dwMajorVersion;
     DLLVersionInfo.dwMinorVersion := p^.dwMinorVersion;

     @DllGetVersion := nil;
     Result := True;
   finally
     dispose(P);
   end;
  // Free the DLL module. 
 // Dll wieder freigeben. 
 FreeLibrary(hInstDll);
 end;

 // Example to get version info from comctl32.dll 
// Beispiel, um von comctl32 Versions/Informationen zu erhalten 

procedure TForm1.Button1Click(Sender: TObject);
 var
   DLLVersionInfo: TDLLVersionInfo;
 begin
  if not GetDllVersion('comctl32.dll',DLLVersionInfo) then
  begin
    DLLVersionInfo.dwMajorVersion := 4;
    DLLVersionInfo.dwMinorVersion := 0;
  end;
  with DLLVersionInfo do
    ShowMessage(Format('ComCtl Version: %d.%d / Build: %d',[dwMajorVersion, dwMinorVersion, dwBuildNumber]))
 end;

Перевод на русский язык:

Код Delphi, который получает информацию о версии DLL-файла (Dynamic Link Library), используя функцию DllGetVersion.

Структура TDLLVersionInfo содержит четыре поля:

  • cbSize: размер структуры в байтах
  • dwMajorVersion, dwMinorVersion и dwBuildNumber: информация о версии DLL

Функция GetDllVersion принимает два параметра: DllName (имя DLL-файла) и DLLVersionInfo (переменная для хранения полученной информации). Она загружает модуль DLL, получает адрес функции DllGetVersion с помощью GetProcAddress, вызывает эту функцию, чтобы получить информацию о версии, и хранит ее в DLLVersionInfo.

Если DLL не экспортирует DllGetVersion, функция возвращает False. Если успешно, она возвращает True и устанавливает DLLVersionInfo с полученной информацией.

В процедуре Button1Click код вызывает GetDllVersion, чтобы получить информацию о версии comctl32.dll. Если получение информации не удалось, он устанавливает значения по умолчанию для информации о версии. Затем он отображает сообщение с полученной информацией в формате "Мажор.Минор / Build".

Некоторые улучшения, которые можно сделать в этом коде:

  1. Обработка ошибок: код не обрабатывает ошибки хорошо. Например, если LoadLibrary fails, процедура выходит из работы без очистки ресурсов. Лучше использовать блок try-except для ловли и обработки исключений.
  2. Управление памятью: код использует new и dispose для управления памятью, что является ошибкой. Лучше использовать умный указатель или управляемый тип для упрощения управления памятью.
  3. Организация кода: код смешивает логику с представлением (отображением информации о версии). Лучше разделить эти Concerns в отдельных процедурах.

Альтернативное решение, которое решает некоторые из этих проблем:

type
  TDLLVersionInfo = record
    cbSize: Cardinal;
    dwMajorVersion, dwMinorVersion, dwBuildNumber: DWORD;
  end;

function GetDllVersion(DllName: string): TDLLVersionInfo;
var
  hInstDll: HMODULE;
  p: PDLLVersionInfo;
begin
  Result := Default(TDLLVersionInfo);
  try
    hInstDll := LoadLibrary(PChar(DllName));
    if hInstDll = 0 then
      Exit;

    @DllGetVersion := GetProcAddress(hInstDll, 'DllGetVersion');
    if @DllGetVersion = nil then
    begin
      FreeLibrary(hInstDll);
      Exit;
    end;

    new(p);
    try
      ZeroMemory(p, SizeOf(TDLLVersionInfo));
      p^.cbSize := SizeOf(TDLLVersionInfo);

      DllGetVersion(p);

      Result.dwMajorVersion := p^.dwMajorVersion;
      Result.dwMinorVersion := p^.dwMinorVersion;
    finally
      dispose(p);
    end;

  finally
    FreeLibrary(hInstDll);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  DLLVersionInfo: TDLLVersionInfo;
begin
  if not GetDllVersion('comctl32.dll') then
  begin
    // Обработка ошибки или установка значений по умолчанию
  end;

  with DLLVersionInfo do
    ShowMessage(Format('ComCtl Version: %d.%d / Build: %d', [dwMajorVersion, dwMinorVersion, dwBuildNumber]));
end;

В этом коде используется блок try-except для ловли исключений и обработки ошибок лучше. Код также разделен на логику получения информации о версии и отображения ее в отдельных процедурах. Я удалил вызовы new и dispose, а вместо них использовал умный указатель (PDLLVersionInfo) для упрощения управления памятью.

Функция DllGetVersion позволяет получать специфическую для DLL информацию о версии, что позволяет приложениям определять присутствующие на системе DLL и их версии.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: DLL и PlugIns ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-19 13:29:56
2024-11-21 12:07:48/0.0042998790740967/0