Пятница, 07.05.2021, 12:25
PureBasic - кроссплатформенный язык программирования
Главная Форум Регистрация Вход
Приветствую Вас, Гость · RSS
Меню сайта
Категории раздела
Начинающим [8]
Статьи
[16.06.2011][Начинающим]
Как быстро найти описание функции или оператора. (0)
[11.06.2011][Начинающим]
Создание EXE программы. (3)
[24.03.2011][Начинающим]
Работа с отладчиком (0)
[17.03.2011][Начинающим]
Замена значка в исполняемом файле (2)
[15.03.2011][Начинающим]
Перезагрузка процедур. (0)
[09.03.2011][Начинающим]
Создание самораспаковывающегося ZIP архива (0)
[24.02.2011][Начинающим]
Работа с ZIP архивами (0)
[22.02.2011][Начинающим]
Определение IP адреса компьютера (0)
Файлы
[28.06.2011][Примеры]
Примеры программ. (1)
[27.06.2011][PB 4.50 и 4.51]
PortLib - работа с портами компьютера (2)
[10.04.2011][PB 4.50 и 4.51]
PureSMTP - отправка почты (2)
[10.03.2011][Примеры]
3D демки. (1)
[10.03.2011][Примеры]
2D демка. (0)
[09.03.2011][PB 4.50 и 4.51]
Русская справка (0)
[09.03.2011][PB 4.50 и 4.51]
Русификатор PureBasic (1)
[02.03.2011][PB 4.50 и 4.51]
HID_Lib - работа с USB HID устройствами. (9)
[01.03.2011][Примеры]
CodeArchiv_v4-Beta (0)
[28.02.2011][Учебники]
Установка PureBasic на ОС Linux (0)
 Каталог статей
Главная » Статьи » Учебные материалы » Начинающим

Создание самораспаковывающегося ZIP архива
В этой статье рассмотрим принцип создания самораспаковывающегося ZIP архива, который может быть защищен паролем.
Эта статья является продолжением статьи о ZIP архивах.
Как и в предыдущей статье, для работы с ZIP архивами, будем использовать библиотеку PureZIP.

Самораспаковывающийся архив состоит из модуля распаковки, находящегося в начале файла и архива, расположенного после модуля распаковки. По большому счету, это просто обычный исполняемый файл (EXE программа) в конце которого находится архив.
Другими словами, для того чтобы создать самораспаковывающийся архив нужно написать небольшую программу распаковки, скомпилировать ее (создать исполняемый файл) и в ее конец, дописать заранее созданный архив.

Итак, создадим простенький распаковщик для ZIP архива.

Программа позволяет выбрать место распаковки и распаковать архив. Если он защищен паролем, то появится окно ввода пароля архива.

Код:
Enumeration
 
#Window_0
EndEnumeration

Enumeration
 
#Text_0
 
#String_PathExtract
 
#Button_Browse
 
#Button_Extract
 
#Text_2
 
#ProgressBar_0
 
#Text_3
 
#Text_ExtractFiles
EndEnumeration
 
Global DoneFiles, ProgName.s=ProgramFilename() 
Procedure Open_Window_0()
 
If
OpenWindow(#Window_0, 334, 311, 334, 120,"Самораспаковывающийся ZIP архив",#PB_Window_MinimizeGadget|#PB_Window_TitleBar|#PB_Window_Invisible|#PB_Window_ScreenCentered)
     
TextGadget
(#Text_0, 5, 5, 315, 15,"Куда распаковать файлы:")
     
StringGadget
(#String_PathExtract, 5, 20, 290, 20,"",#PB_String_ReadOnly)
     
ButtonGadget
(#Button_Browse, 300, 20, 24, 20,"...")
  
   ButtonGadget
(#Button_Extract, 240, 90, 90, 25,"Распаковать")
     
TextGadget
(#Text_2, 5, 90, 235, 30,"Пример создан в среде PureBasic 4.51 с использованием библиотеки PureZIP.")
     
ProgressBarGadget
(#ProgressBar_0, 5, 65, 325, 15, 0, 100,#PB_ProgressBar_Smooth)
     
TextGadget
(#Text_3, 5, 50, 70, 15,"Распаковка:")
     
TextGadget
(#Text_ExtractFiles, 80, 50, 250, 15,"")
 
EndIf
EndProcedure
 
Procedure PureSFXCallback(File.s, PerCent); Отображение в окне общего прогресса распаковки файлов
 
Result=0
 
SetGadgetText
(#Text_ExtractFiles, File)
 
SetGadgetState
(#ProgressBar_0, DoneFiles*100/PerCent)
 
DoneFiles+1 
  Repeat
   
Event=WindowEvent()
   
If
Event=#PB_Event_CloseWindow
     
If
EventWindow()=#Window_0
       
Select
MessageRequester(GetFilePart(ProgName),"Закрыть окно с остановкой распаковки файлов?",#MB_YESNOCANCEL|#MB_ICONQUESTION|#MB_DEFBUTTON2)
         
Case
#IDYES
           
End
         
Case
#IDCANCEL
           
Result = 1
       
EndSelect
     
EndIf
  
 EndIf
 
Until
Event = 0 
  ProcedureReturn Result
EndProcedure

Procedure ExtractArchive(ExtractPath.s); Распаковка архива в папку ExtractPath
 
GlobalInfo
.unz_global_info
 
FileInfo
.PureZIP_FileInfo
 
PureZIP_SetArchivePassword
("")
 
CountFiles=PureZIP_GetFileCount(ProgName); Число файлов в архиве 
  For i=0 To CountFiles-1 ; Выясняем запараролен ли архив
   
If
PureZIP_GetFileInfo(ProgName,i,@FileInfo)=#True
      
If
FileInfo\flag & 1 = 1
       
Pass.s=InputRequester(GetFilePart(ProgName)+" - Архив защищён паролем!","Введите пароль архива","")
       
PureZIP_SetArchivePassword
(Pass)
       
Break
     
EndIf
   
EndIf
 
Next
i 
  If PureZIP_Archive_Read(ProgName) ; Открываем архив (исполняемый файл распаковщика)
   
DoneFiles=1
   
PureZIP_Archive_GlobalInfo
(@GlobalInfo)
    
NrOfCompressed.l = GlobalInfo\number_entry
   
ReturnValue.l = PureZIP_Archive_FindFirst()
   
While
ReturnValue =#UNZ_OK
     
If
PureZIP_Archive_FileInfo(@FileInfo)=#UNZ_OK           ; Данные о файле (размер, дата, степень сжатия, CRC и т. д.)
       
If
PureZIP_Archive_Extract(ExtractPath,#True)=#UNZ_OK  ; Распаковываем файлы
         
If
PureSFXCallback(FileInfo\FileName, NrOfCompressed)= 1
           
Break
; Распаковка прервана пользователем.
         
EndIf

         
ReturnValue = PureZIP_Archive_FindNext(); Подготовка к распаковке следующего файла
       
Else

         
MessageRequester
("","Произошла ошибка при распаковке файла"+Chr(10)+FileInfo\FileName,#MB_OK|#MB_ICONWARNING)
         
Break
       
EndIf
     
EndIf
   
Wend
   
    PureZIP_Archive_Close() ; Закрытие архива
    If ReturnValue =#UNZ_END_OF_LIST_OF_FILE
     
SetGadgetText
(#Text_ExtractFiles,"Архив успешно распакован")
     
MessageRequester
(GetFilePart(ProgName),"Архив успешно распакован.",#MB_OK|#MB_ICONINFORMATION)
   
EndIf
   
EndIf
EndProcedure

Open_Window_0()
SetGadgetText
(#String_PathExtract, GetPathPart(ProgramFilename()))
HideWindow
(#Window_0,0) 
Repeat ; Главный цикл Repeat - Until
 
Event = WaitWindowEvent() ; Идентификатор события 
  
If
Event =#PB_Event_Gadget
   
Select
EventGadget() ; Идентификатор гаджета по которому кликнули
     
Case
#Button_Browse
       
Path.s=PathRequester("Укажите путь к месту распаковки файлов","")
       
If
FileSize(Path)=-2 ; Папка существует
         
SetGadgetText
(#String_PathExtract, Path)
       
EndIf

       

      
Case
#Button_Extract
       
Path.s=GetGadgetText(#String_PathExtract)
       
If
FileSize(Path)=-2 ; Папка существует
         
ExtractArchive
(Path)
       
Else

         
MessageRequester
("","Укажите путь к месту распаковки файлов!",#MB_OK|#MB_ICONWARNING)
       
EndIf
   
EndSelect
 
EndIf

Until Event =#PB_Event_CloseWindow


При клике по кнопке "Распаковать" будет вызвана процедура ExtractArchive. Ее код сначала посчитает файлы в архиве, а затем просмотрит все файлы чтобы выяснить есть ли среди них зашифрованные. В случае, если таковые будут обнаружены, будет создано окно с запросом пароля архива. Затем, открывается архив для чтения функцией PureZIP_Archive_Read. В цикле While - Wend, файлы извлекаются из архива функцией PureZIP_Archive_Extract. Когда все файлы будут извлечены, архив  закрывается функцией PureZIP_Archive_Close.
Вот собственно и все - самораспаковывающиеся архивы довольно просто устроены.

Как отмечалось выше, самораспаковывающийся архив состоит из исполняемого файла (EXE программы) и архива. Теперь рассмотрим как правильно дописать архив в конец скомпилированного исполняемого файла распаковщика. Конечно же, вручную делать это утомительно и легко ошибиться! Для этого, была немного доработана заготовка программы упаковщика программ. Была модифицирована процедура, выполняемая при щелчке по экранной кнопке в окне программы.

Код:
Procedure Button_Archive(Directory.s, File.s)
  *Mem = AllocateMemory(100000) ; Память (100 тысяч байт) для копирования данных из временного архива в самораспаковывающийся.
  If *Mem
   
TempDir.s=GetTemporaryDirectory() ; Определение пути к временной папке
   
If
FileSize(TempDir) = -2
      Repeat ; Генерация имени временного файла архива
       
ArcFile.s = TempDir + "$$"+Str(Random(100000))+"xx.tmp"
     
Until
FileSize(ArcFile) = -1
     
; Упаковка файлов
      If PureZIP_AddFiles(ArcFile, Directory+"*.*", #PureZIP_StorePathRelative, #PureZIP_Recursive) > 0
        If ReadFile(0,ArcFile) ; Открыли временный файл архива
         
ArchiveSize=Lof(0)   ; Размер этого файла
          If CreateFile(1,File) ; Создаем файл самораспаковывающегося архива
           
WriteData
(1, ?SFX_File, ?SFX_File_End-?SFX_File) ; В начало файла - модуль распаковки архива.
            While Eof(0) = 0 ; Копирование данных из временного в самораспаковывающийся архив
              CountBytes = ReadData(0,*Mem,100000)
              If CountBytes>0
               
WriteData
(1,*Mem,CountBytes)
              EndIf
            Wend
           
WriteLong(1,ArchiveSize) ; Дописывание в конец самораспаковывающегося архива, размер архива.
            CloseFile(1)
            SetGadgetText(#Text_CurrentFiles, "Самораспаковывающийся архив создан")
            MessageRequester("", "Самораспаковывающийся архив создан.", #MB_OK|#MB_ICONINFORMATION)
          Else
            MessageRequester("", "Не удалось создать файл!", #MB_OK|#MB_ICONERROR)
          EndIf
         
CloseFile
(0)
        Else
         
MessageRequester
("", "Не удалось открыть архив для чтения!", #MB_OK|#MB_ICONERROR)
        EndIf
       Else
        MessageRequester("", "Ошибка при упаковке файлов!", #MB_OK|#MB_ICONERROR)
      EndIf
      DeleteFile(ArcFile) ; Удаление временного файла ZIP архива.
    Else
     
MessageRequester
("", "Не обнаружена временная папка Windows!", #MB_OK|#MB_ICONERROR)
    EndIf
  Else
   
MessageRequester
("", "Не удалось выделить память!", #MB_OK|#MB_ICONERROR)
  EndIf
EndProcedure


В этой процедуре в создается временный файл под архив, а затем, в него добавляются файлы из выбранной папки. Потом, создается пустой файл под самораспаковывающийся архив и в его начало записывается тело исполняемого файла (строка "WriteData(1, ?SFX_File, ?SFX_File_End-?SFX_File)" ), а затем, в его конец, копируется содержимое архива из временного файла, после чего, файлы закрываются и удаляется временный файл с архивом.



Здесь был рассмотрен относительно простой пример, самораспаковывающегося архива, но в зависимости от реализуемой задачи его можно изменить (не зря же исходники выкладываю), скажем, вообще не отображать окно распаковщика, что позволит распаковывать файлы вскрытом режиме сразу после щелчка по архиву.
Категория: Начинающим | Добавил: fils (09.03.2011)
Просмотров: 8360 | Теги: SFX, ZIP, самораспаковывающейся архив, PureZIP | Рейтинг: 0.0/0
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Copyright MyCorp © 2021
Форма входа

Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0
Поиск
Друзья сайта
  • Разработчики PureBasic
  • Русский сайт о PureBasic
  • pure-basic.narod.ru
  • mirashic.narod.ru
  • purebasic.ucoz.com
  • purebasic.org
  • purebasic.ru
  • Копировать материалы сайта без разрешения автора, ЗАПРЕЩЕНО!

    Сделать бесплатный сайт с uCoz