Что нового

[Файловая система] Упаковка файлов в один исполняемый файл

joiner

Модератор
Локальный модератор
Сообщения
3,570
Репутация
632
Версия AutoIt
3.3.16.1
Версия
1.0
AutoIt: 3.3.16.1
Версия: 1.0

Категория: Вспомогательные функции

Описание: Это не проект, а пример, идея. не новая, но все же
Записываем все нужные файлы в один. Этот файл своего рода "самораспаковывающийся архив". Запускаем файл и можно извлечь все файлы или только выбранные. Весь код очень прост.
В данном примере не используется сжатие, но его можно добавить при желании.

Запускаем файл Kit.au3, выбираем папку с файлами. ждем окончания процесса
Код/Пример:
Код:
#include <FileOperations.au3>
$fsf = FileSelectFolder('', '')
If @error Then Exit
$filear = _FO_FileSearch($fsf)
If @error Then Exit
Local $sizeall = DirGetSize($fsf)
$fo = FileOpen('install.au3', 2)
FileWriteLine($fo, 'Global $array[' & UBound($filear) - 1 & '][2]')
Local $size, $index = 0
For $i = 1 To $filear[0]
    FileWriteLine($fo, '$array[' & $index & '][0]=' & '"' & StringReplace($filear[$i], $fsf, '') & '"')
    FileWriteLine($fo, '$array[' & $index & '][1]=' & "'" & FileGetSize($filear[$i]) & "'")
    $index += 1
Next
$fr = FileRead('listw.au3')
FileWrite($fo, $fr)
FileClose($fo)
Local $perc, $sizein
$AutoITPath = RegRead('HKEY_LOCAL_MACHINE\SOFTWARE\AutoIt v3\AutoIt', 'InstallDir')
If @error Then Exit
RunWait($AutoITPath & '\Aut2Exe\Aut2Exe.exe /in install.au3 /icon pack.ico')
ProgressOn('Собираю', 'Текущий файл')
$fo1 = FileOpen('install.exe', 17)
For $i = 1 To $filear[0]
    $fo2 = FileOpen($filear[$i], 16)
    $fr1 = FileRead($fo2)
    $sizein += @extended
    $perc = Floor($sizein / $sizeall * 100)
    ProgressSet($perc, StringRegExpReplace($filear[$i], '.*\\', ''))
    FileWrite($fo1, $fr1)
    FileClose($fo2)
Next
ProgressSet(100)
FileClose($fo1)

Второй файл listw.au3 это оболочка "распаковщика". исполняемая часть. он должен быть в одной папке с первым файлом
Код/Пример:
Код:
#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <ListViewConstants.au3>
#include <WindowsConstants.au3>
#include <WinApi.au3>
#include <GuiListView.au3>
#include <array.au3>
$Form1 = GUICreate("Form1", 615, 460, -1, -1, BitOR($GUI_SS_DEFAULT_GUI, $WS_MAXIMIZEBOX, $WS_TABSTOP))
Global $label = GUICtrlCreateLabel('', 16, 430, 600, 12)
$ListView1 = GUICtrlCreateListView("", 16, 16, 578, 374, $LVS_SHOWSELALWAYS + $LVS_NOSORTHEADER, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT))
_GUICtrlListView_AddColumn($ListView1, 'Файл', 350)
_GUICtrlListView_AddColumn($ListView1, 'Размер в байтах', 228)
$Button1 = GUICtrlCreateButton("Извлечь все", 16, 400, 75, 25)
$Button2 = GUICtrlCreateButton("Извлечь", 503, 400, 75, 25)
GUISetState(@SW_SHOW)
Local $index = 0
For $i = 0 To UBound($array) - 1
    _GUICtrlListView_AddItem($ListView1, $array[$i][0])
    _GUICtrlListView_AddSubItem($ListView1, $index, $array[$i][1], 1)
    $index += 1
Next

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $Button1
            _unpack()
            GUICtrlSetData($label, 'Готово!!!')
        Case $Button2
            $getselect = _GUICtrlListView_GetSelectedIndices($ListView1, True)
            If IsArray($getselect) Then
                If $getselect[0] <> 0 Then _unpackselect($getselect)
            EndIf
    EndSwitch
WEnd

Func _unpack()
    Local $path = FileSelectFolder('', '')
    If @error Then Return
    Local $allsize
    Local $wincr = _WinAPI_CreateFile(@ScriptFullPath, 2, 2)
    For $i = UBound($array) - 1 To 0 Step -1
        GUICtrlSetData($label, $path & $array[$i][0])
        Local $nBytes, $tBuffer
        $allsize += $array[$i][1]
        $tBuffer = DllStructCreate('byte[' & $array[$i][1] & ']')
        _WinAPI_SetFilePointer($wincr, -$allsize, 2)
        _WinAPI_ReadFile($wincr, DllStructGetPtr($tBuffer), $array[$i][1], $nBytes)
        Local $fo2 = FileOpen($path & $array[$i][0], 26)
        FileWrite($fo2, DllStructGetData($tBuffer, 1))
        FileClose($fo2)
    Next
    _WinAPI_CloseHandle($wincr)
EndFunc   ;==>_unpack


Func _unpackselect($aindex)
    Local $path = FileSelectFolder('', '')
    If @error Then Return
    Local $wincr = _WinAPI_CreateFile(@ScriptFullPath, 2, 2)
    Local $allsize
    For $i = UBound($array) - 1 To 0 Step -1
        $allsize += $array[$i][1]
        For $r = $aindex[0] To 1 Step -1
            If $aindex[$r] = $i Then
                Local $nBytes, $tBuffer
                $tBuffer = DllStructCreate('byte[' & $array[$i][1] & ']')
                _WinAPI_SetFilePointer($wincr, -$allsize, 2)
                _WinAPI_ReadFile($wincr, DllStructGetPtr($tBuffer), $array[$i][1], $nBytes)
                Local $fo2 = FileOpen($path & $array[$i][0], 26)
                FileWrite($fo2, DllStructGetData($tBuffer, 1))
                FileClose($fo2)
                ExitLoop
            EndIf
        Next
    Next
    _WinAPI_CloseHandle($wincr)
EndFunc   ;==>_unpackselect

После "упаковки" появится файл install.exe , то есть сам "распаковщик", который будет включать в себя все указанные файлы. запускаем его. ну и дальше все будет понятно интуитивно

Источник: autoit-script.ru
Автор(ы): joiner
Сообщение автоматически объединено:

изменил пример. распаковка с использованием нативных функций. в данном примере можно извлекать как выборочно, так и все файлы
Файл kit
Код:
#include <Array.au3>

Local $PATHCOMPILE = @ScriptDir & '\ResFileEx.exe'
If FileExists($PATHCOMPILE) Then FileDelete($PATHCOMPILE)
Local $sZipDir = @ScriptDir & '\Resources'; папка с файлами должна быть
Local $sAu3 = @ScriptDir & '\ResFile.au3'
Local $sAu3Ex = @ScriptDir & '\ResFileEx.au3'
Local $hOpenFileRes, $bReadFale
Local $hOpenfileDest, $sReadAu3
Local $aFilesInstall = _FileListToArray($sZipDir, '*', 1), $nSizeZip, $nExtRead, $nProcSet, $nFilesize
If @error Then Exit
Local $sFileCod = "Global $aDataZipPos[" & $aFilesInstall[0] & "][2]" & @LF
For $i = 1 To $aFilesInstall[0]
    $sFileCod &= "$aDataZipPos[" & $i - 1 & "][0]=" & "'" & $aFilesInstall[$i] & "'"& @LF
    $sFileCod &= "$aDataZipPos[" & $i - 1 & "][1]=" & FileGetSize($sZipDir & '\' & $aFilesInstall[$i]) & @LF
Next
FileCopy($sAu3, $sAu3Ex, 1)
$sReadAu3 = $sFileCod & FileRead($sAu3)
Local $hOres = FileOpen($sAu3Ex, 2)
FileWrite($hOres, $sReadAu3)
FileClose($hOres)
RunWait('C:\Program Files (x86)\AutoIt3\Aut2Exe\Aut2Exe.exe /in "' & $sAu3Ex & '"'); указать путь к Aut2Exe.exe
FileDelete($sAu3Ex)
$nSizeZip = DirGetSize($sZipDir)
$hOpenfileDest = FileOpen($PATHCOMPILE, 17)
For $i = 1 To $aFilesInstall[0]
    $nFilesize = FileGetSize($sZipDir & '\' & $aFilesInstall[$i])
    $hOpenFileRes = FileOpen($sZipDir & '\' & $aFilesInstall[$i], 16)
    While 1
        $bReadFale = FileRead($hOpenFileRes, 1048576)
        If @error = -1 Then ExitLoop
        $nExtRead += @extended
        $nProcSet = Floor($nExtRead / $nSizeZip * 100)
        ConsoleWrite($nProcSet & @LF)
        FileWrite($hOpenfileDest, $bReadFale)
    WEnd
    FileClose($hOpenFileRes)
Next
FileClose($hOpenfileDest)

файл для компиляции ResFile

Код:
#include <GuiTreeView.au3>
#include <WindowsConstants.au3>

Local $sDest = @ScriptDir & '\Dest'
Local $Form1 = GUICreate("Form1", 615, 500, -1, -1, BitOR($GUI_SS_DEFAULT_GUI, $WS_MAXIMIZEBOX, $WS_TABSTOP))
Local $TreeW = GUICtrlCreateTreeView(16, 16, 578, 374, BitOR($TVS_HASBUTTONS, $TVS_HASLINES, $TVS_CHECKBOXES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS), $WS_EX_CLIENTEDGE)
Global $hTreeW = GUICtrlGetHandle($TreeW)
Local $Button1 = GUICtrlCreateButton("ExtractAll", 16, 400, 75, 25)
Local $Button2 = GUICtrlCreateButton("Extract", 503, 400, 75, 25)
Local $Button3 = GUICtrlCreateButton("UnCheckAll", 350, 400, 75, 25)
Local $Button4 = GUICtrlCreateButton("CheckAll", 200, 400, 75, 25)
Local $LBinfo = GUICtrlCreateLabel('', 16, 435, 300, 30)
Local $aSelItem
For $i = 0 To UBound($aDataZipPos) - 1
     _GUICtrlTreeView_Add($hTreeW, $i, $aDataZipPos[$i][0])
Next
GUISetState(@SW_SHOW)

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case -3
            Exit
        Case $Button1
            $aSelItem = _GetSAll()
            _ExtractFiles($aSelItem, $sDest, $aDataZipPos, @ScriptFullPath)
        Case $Button2
            Local $aSelItem = _GetSel()
            _ExtractFiles($aSelItem, $sDest, $aDataZipPos, @ScriptFullPath)
        Case $Button3
            _UnChkSet(0)
        Case $Button4
            _UnChkSet(1)
    EndSwitch
WEnd

Func _GetSel()
    Local $hFst = _GUICtrlTreeView_GetFirstItem($hTreeW)
    If Not $hFst Then Return
    Local $sTNM
    If _GUICtrlTreeView_GetChecked($hTreeW, $hFst) Then $sTNM &= _GUICtrlTreeView_GetText($hTreeW, $hFst) & '|'
    While 1
        $hFst = _GUICtrlTreeView_GetNext($hTreeW, $hFst)
        If Not $hFst Then ExitLoop
        If _GUICtrlTreeView_GetChecked($hTreeW, $hFst) Then $sTNM &= _GUICtrlTreeView_GetText($hTreeW, $hFst) & '|'
    WEnd
    $sTNM = StringTrimRight($sTNM, 1)
    $sTNM = StringSplit($sTNM, '|', 3)
    Return $sTNM
EndFunc   ;==>_GetSel

Func _UnChkSet($Nflag)
    Local $hFst = _GUICtrlTreeView_GetFirstItem($hTreeW)
    If Not $hFst Then Return
    _GUICtrlTreeView_SetChecked($hTreeW, $hFst, $Nflag)
    While 1
        $hFst = _GUICtrlTreeView_GetNext($hTreeW, $hFst)
        If Not $hFst Then ExitLoop
        _GUICtrlTreeView_SetChecked($hTreeW, $hFst, $Nflag)
    WEnd
EndFunc   ;==>_UnChkSet

Func _GetSAll()
    Local $hFst = _GUICtrlTreeView_GetFirstItem($hTreeW)
    If Not $hFst Then Return
    Local $sTNM
    $sTNM &= _GUICtrlTreeView_GetText($hTreeW, $hFst) & '|'
    While 1
        $hFst = _GUICtrlTreeView_GetNext($hTreeW, $hFst)
        If Not $hFst Then ExitLoop
        $sTNM &= _GUICtrlTreeView_GetText($hTreeW, $hFst) & '|'
    WEnd
    $sTNM = StringTrimRight($sTNM, 1)
    $sTNM = StringSplit($sTNM, '|', 3)
    Return $sTNM
EndFunc   ;==>_GetSAll

Func _ExtractFiles($aNameExt, $sPathExt, $aArrayFiles, $sPathExe)
    Local $hFileCreateST, $nAllSizeFiles, $bReadFile
    $hFileCreateST = FileOpen($sPathExe, 16)
    If $hFileCreateST = -1 Then Return SetError - 25
    For $r = 0 To UBound($aNameExt) - 1
        For $i = UBound($aArrayFiles) - 1 To 0 Step -1
            $nAllSizeFiles += $aArrayFiles[$i][1]
            If $aArrayFiles[$i][0] = $aNameExt[$r] Then
                FileSetPos($hFileCreateST, -$nAllSizeFiles, 2)
                $bReadFile = FileRead($hFileCreateST, $aArrayFiles[$i][1])
                $hOfileRes = FileOpen($sPathExt & '\' & $aArrayFiles[$i][0], 26)
                FileWrite($hOfileRes, $bReadFile)
                FileClose($hOfileRes)
                ExitLoop
            EndIf
        Next
        $nAllSizeFiles = 0
    Next
    FileClose($hFileCreateST)
EndFunc   ;==>_ExtractFiles
 
Последнее редактирование:
  • Like
Реакции: Norm
Верх