Что нового

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

joiner

Модератор
Локальный модератор
Сообщения
3,557
Репутация
628
AutoIt: 3.3.12.0
Версия: 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
 
Верх