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

Создаём собственный UnRar, используя unrar.dll

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

Создаём собственный UnRar, используя unrar.dll

Едут в переполненном автобусе качок, каратист и программист. Измученный толкотней качок предлагает:
- Давайте, ребята, поднажмем и лишний народ вытолкнем.
Каратист не согласен:
- Да, ну, давайте лучше замочим человек пять, а остальные сами разбегутся.
Программист с умным лицом предлагает:
- Зачем мучиться, давайте лучше заархивируем всех и положим на переднее сиденье.


// Объявления

function RAROpenArchive(ArchiveData : Pointer): Integer; stdcall;
external 'unrar.dll' name 'RAROpenArchive';

function RARCloseArchive(hArcData : Integer): Integer; stdcall;
external 'unrar.dll' name 'RARCloseArchive';

function RARReadHeader(hArcData : Integer; HeaderData : Pointer):
Integer; stdcall;
external 'unrar.dll' name 'RARReadHeader';

function RARProcessFile(hArcData : Integer; Operation : Integer;
DestPath : Pointer; DestName : Pointer): Integer; stdcall;
external 'unrar.dll' name 'RARProcessFile';


const
  ERAR_END_ARCHIVE = 10;
  ERAR_NO_MEMORY = 11;
  ERAR_BAD_DATA = 12;
  ERAR_BAD_ARCHIVE = 13;
  ERAR_UNKNOWN_FORMAT = 14;
  ERAR_EOPEN = 15;
  ERAR_ECREATE = 16;
  ERAR_ECLOSE = 17;
  ERAR_EREAD = 18;
  ERAR_EWRITE = 19;
  ERAR_SMALL_BUF = 20;

  RAR_OM_LIST = 0;
  RAR_OM_EXTRACT = 1;
  RAR_SKIP = 0;
  RAR_TEST = 1;
  RAR_EXTRACT = 2;
  RAR_VOL_ASK = 0;
  RAR_VOL_NOTIFY = 1;

type
  Char260 = array [1..260] of Char;

  TRAROpenArchiveData = record
    ArcName : PChar; // в C++ это будет выглядеть как: char *ArcName
    OpenMode : Cardinal;
    OpenResult : Cardinal;
    CmtBuf : PChar;
    CmtBufSize : Cardinal;
    CmtSize : Cardinal;
    CmtState : Cardinal;
  end;

  TRARHeaderData = record
    ArcName : Char260;
    FileName : Char260;
    Flags : Cardinal;
    PackSize : Cardinal;
    UnpSize : Cardinal;
    HostOS : Cardinal;
    FileCRC : Cardinal;
    FileTime : Cardinal;
    UnpVer : Cardinal;
    Method : Cardinal;
    FileAttr : Cardinal;
    CmtBuf : PChar;
    CmtBufSize : Cardinal;
    CmtSize : Cardinal;
    CmtState : Cardinal;
  end;


var
  RARExtract : boolean;
  RAROpenArchiveData : TRAROpenArchiveData;
  RARComment : array [1..256] of Char;
  RARHeaderData : TRARHeaderData;

...

procedure ExtractRARArchive;
var
  sDir : string;
  s : string;
  sTest : string;
  iTest : integer;
  bTestDone : boolean;
  RARhnd : Integer;
  RARrc : Integer;
  PDestPath : Char260;
begin
  RARExtract:=TRUE;
  lKBWritten:=0;
  ProgressBar2.Position := 0;
  ProgressBar2.Max := lTotalSize;
  RARStartTime:=Time;

  RAROpenArchiveData.OpenResult:=99;
  RAROpenArchiveData.OpenMode := RAR_OM_EXTRACT; // открываем для распаковки
  RAROpenArchiveData.ArcName:= @RARFileName;
  RAROpenArchiveData.CmtBuf := @RARComment;
  RAROpenArchiveData.CmtBufSize := 255;

  // Открываем RAR архив и выделяем память
  RARhnd := RAROpenArchive (@RAROpenArchiveData);
  if RAROpenArchiveData.OpenResult <> 0 then
  begin
    case RAROpenArchiveData.OpenResult of
      ERAR_NO_MEMORY   : s:='Not enough memory to initialize data structures';
      ERAR_BAD_DATA    : s:='Archive header broken';
      ERAR_BAD_ARCHIVE : s:='File is not valid RAR archive';
      ERAR_EOPEN       : s:='File open error';
    end;
    MessageDlg('Unable to open rar archive: ' + s + '!',mtError, [mbOK], 0);
  end;

  RARSetProcessDataProc(RARhnd,@Form.OnRarStatus);
  StrPCopy(@PDestPath, EInstallPath.Text);

  repeat
    RARrc := RARReadHeader (RARhnd, @RARHeaderData);// Читаем заголовок
    if RARrc <> ERAR_END_ARCHIVE then
    begin
      ProgressBar1.Position := 0;
      ProgressBar1.Max := RARHeaderData.UnpSize;
      s:=RARHeaderData.FileName;
      lblCurrentFile.Caption := s;
      lKBytesDone := 0;
    end;

    if RARrc = 0 then
      RARrc:=RARProcessFile (RARhnd, RAR_EXTRACT, @PDestPath, nil);
    if (RARrc <> 0) and (RARrc <> ERAR_END_ARCHIVE) then
    begin
      MessageDlg('An Error occured during extracting of ' + sTest+'!' + #13#10 +
      'RARProcessFile: ' + MakeItAString(RARrc),mtError, [mbOK], 0);
    end;
  until
    RARrc <> 0;

  // закрываем RAR архив и освобождаем память
  if RARCloseArchive(RARhnd) <> 0 then
  begin
    MessageDlg('Unable to close rar archive!',mtError, [mbOK], 0);
  end;
end;

Перед тем, как мы начнем обзор кода и предложения, хотел бы обратить внимание, что использование внешнего DLL-файла, такого как unrar.dll, может быть хорошей идеей, но также ограничивает портативность и поддержку вашего программного обеспечения.

Теперь давайте более подробно рассмотрим код:

Декларации функций Функциональные декларации для RAROpenArchive, RARCloseArchive, RARReadHeader и RARProcessFile корректны. Однако, вам может быть полезно использовать более описательное наименование для этих функций, например, OpenRarArchive, CloseRarArchive и т.д.

Константные определения Константные определения для кодов ошибок (например, ERAR_END_ARCHIVE) и других значений (например, RAR_OM_EXTRACT) полезны. Вам может быть полезно группировать их в отдельный модуль или единицу для лучшей организации кода.

Типовые определения Типовые определения для TRAROpenArchiveData и TRARHeaderData корректны. Однако, вам может быть полезно добавить комментарии, объясняющие, что каждый поле представляет собой.

Декларации переменных Декларации переменных для RARExtract, RAROpenArchiveData, RARComment и т.д. корректны.

Процедура ExtractRARArchive Эта процедура является основным точкой входа для извлечения архива RAR. Вот некоторые предложения:

  1. Обработка ошибок: Вы уже проверяете ошибки в RAROpenArchive и RARCloseArchive. Однако, вам может быть полезно реализовать более robust обработку ошибок по всему процессу.
  2. Обновление прогресс-бара: Вы обновляете прогресс-бар вручную, используя ProgressBar1.Position и ProgressBar1.Max. Вам может быть полезно использовать более эффективный подход, например, свойство TProgressBar.Progress или реализовать свою механику обновления прогресс-бара.
  3. Цикл извлечения файлов: Цикл извлечения файлов использует конструкцию repeat...until, чтобы извлечь файлы из архива RAR. Вам может быть полезно разбить это на отдельные процедуры или функции для лучшей организации кода и читаемости.
  4. Обработка строк: Вы используете конкатенацию строк, чтобы построить сообщения об ошибках в нескольких местах. Вам может быть полезно использовать более эффективный подход, например, функцию Format или реализовать свою механику создания сообщений об ошибках.

Альтернативное решение Если вы ищете альтернативное решение, вам может быть полезно рассмотреть использование библиотеки Delphi, которая предоставляет возможности извлечения архивов RAR без использования внешнего DLL-файла, такого как unrar.dll. Например, вы можете использовать компонент RarArchive из библиотеки SynEdit или реализовать свою логику извлечения архивов RAR с помощью встроенных ZIP и TAR-библиотек Delphi.

Надеюсь, это поможет! Пожалуйста, дайте мне знать, если у вас есть какие-либо дополнительные вопросы.

Создаём собственный UnRar, используя unrar.dll: в статье рассматривается создание программы для распаковки архивов RAR с использованием функций из динамической библиотеки unrar.dll.


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

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




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


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


реклама


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

Время компиляции файла: 2024-12-22 20:14:06
2025-01-29 01:53:18/0.024730920791626/1