[Release] CAB UDF

03/28/2013 13:59 Achat#1
Hi epvp!

Gestern habe ich nach einem einfachen weg gesucht, eine *.ini Datei zu komprimieren, möglichst ohne irgendwelche Fremdprogramme zu benutzen, die ja zusätzlich Speicherplatz benötigen.
Das ist dann dabei rausgekommen:

Code:
#include-once
; #FUNCTION# ====================================================================================================================
; Name ..........: _Cab
; Description ...: Compress/decompress ONE file.
; Syntax ........: _Cab($sFileIn[, $sFileOut = Default])
; Parameters ....: $sFileIn             - Input File
;                  $sFileOut            - [optional] Output file
;
;                 If $sFileIn is a cab (compressed) file and $sFileOut = Default Then extract the file in the same directory as $sFileIn, with its compressed name.
;                 If $sFileIn is a cab (compressed) file and $sFileOut <> Default Then extract the file in $sFileOut
;                 If $sFileIn is an uncompressed file and $sFileOut = Default Then for example $sFileIn = Test.txt, $sFileOut = Test.cab (rename extension)
;                 If $sFileIn is an uncompressed file and $sFileOut <> Default Then save the compressed file under $sFileOut
; Return values .: None
;         @error.: @error > 1 - $sFileIn is a directory
;         @error.: @error > 2 - $sFileIn doesn't exist
; Author ........: Achat
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: No
; ===============================================================================================================================
Func _Cab($sFileIn, $sFileOut = Default)
	If StringInStr(FileGetAttrib($sFileIn), 'D') Then Return SetError(1, 0, 0)
	If Not FileExists($sFileIn) Then Return SetError(2, 0, 0)
	If StringRegExpReplace($sFileIn, '.+\.(.+)', '\1') = 'cab' Then
		If IsKeyword($sFileOut) Then
			$sFileOut = StringRegExpReplace($sFileIn, '((.+)\\.+)', '\1')
			RunWait(@ComSpec & ' /c expand "' & $sFileIn & '" -r "' & $sFileOut & '"', @ScriptDir, @SW_HIDE)
		Else
			RunWait(@ComSpec & ' /c expand "' & $sFileIn & '" "' & $sFileOut & '"', @ScriptDir, @SW_HIDE)
		EndIf
		FileDelete($sFileIn)
	Else
		If IsKeyword($sFileOut) Then $sFileOut = StringRegExpReplace($sFileIn, '(.+\.).+', '\1cab')
		RunWait(@ComSpec & ' /c makecab "' & $sFileIn & '" "' & $sFileOut & '"', @ScriptDir, @SW_HIDE)
		FileDelete($sFileIn)
	EndIf
EndFunc   ;==>_Cab
Beim starten eures Programmes:
_Cab('ini.cab')

Beim beenden eures Programmes:
_Cab('ini.ini')

Es kann damit immer nur eine Datei komprimiert werden.

MfG
03/29/2013 02:26 Croco™#2
Will ja net deine Arbeit schlecht machen (die übrigens gut ist !) aber im Normalfall werden inis dafür verwendet Einstellungen zu speichern.
Was will man da großartig komprimieren ?
03/29/2013 11:13 Lawliet#3
Spiel Speicherstände, ausgewertete Date / Datenbanken ..
08/12/2013 22:33 Achat#4
Quote:
Originally Posted by Achat View Post
Es kann damit immer nur eine Datei komprimiert werden.
Da es beim Komprimieren von mehreren Dateien sehr ineffizient ist, diese einzeln zu packen, habe ich die Funktion erweitert. Nun können mehrere Dateien in einer cab Datei gespeichert werden. Damit wird die Effizienz der Komprimierung erhöht.

Code:
; #FUNCTION# ====================================================================================================================
; Name ..........: _Makecab
; Description ...: Compresses files into a cabinet file.
; Syntax ........: _Makecab($sFileOut, $aFiles)
; Parameters ....: $sFileOut            - A string value. Path where *.cab will be saved.
;                  $aFiles              - An array of strings. 1D array containing path to files.
; Return values .: On success: 1 (-1 = bad array, 0 = makecab fail)
; Author ........: Achat
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: No
; ===============================================================================================================================
Func _Makecab($sFileOut, $aFiles)
	;Extraction: expand /F:* /r "%CD%"
	Local $hFile, $sWrite, $iReturn = 0
	If UBound($aFiles, 0) <> 1 Then Return -1
	$sWrite = '.OPTION EXPLICIT' & @CRLF & _
			'.Set CabinetNameTemplate=cab' & @AutoItPID & '.cab' & @CRLF & _
			'.Set Cabinet=on' & @CRLF & _
			'.Set Compress=on' & @CRLF & _
			'.Set ClusterSize=4096' & @CRLF & _
			'.Set Maxdisksize=' & 4096 * 1024 * 1024 * 1024 & @CRLF & _
			'.Set MaxDiskFileCount=133713371337' & @CRLF
	For $i = 0 To UBound($aFiles) - 1
		$sWrite &= Chr(34) & $aFiles[$i] & Chr(34) & @CRLF
	Next
	$hFile = FileOpen(@TempDir & '\cab' & @AutoItPID & '.ddf', 2)
	FileWrite($hFile, $sWrite)
	FileClose($hFile)
	RunWait(@ComSpec & ' /c makecab /f ' & Chr(34) & @TempDir & '\cab' & @AutoItPID & '.ddf' & Chr(34), @TempDir, @SW_HIDE)
	FileDelete(@TempDir & '\cab' & @AutoItPID & '.ddf')
	FileDelete(@TempDir & '\setup.inf')
	FileDelete(@TempDir & '\setup.rpt')
	$iReturn = FileMove(@TempDir & '\disk1\cab' & @AutoItPID & '.cab', $sFileOut, 1)
	FileDelete(@TempDir & '\disk1\cab' & @AutoItPID & '.cab')
	DirRemove(@TempDir & '\disk1')
	Return $iReturn
EndFunc   ;==>_Makecab

; #FUNCTION# ====================================================================================================================
; Name ..........: _Expand
; Description ...: Extract files from a *.cab file.
; Syntax ........: _Expand($sFileIn[, $sDirOut = Default])
; Parameters ....: $sFileIn             - A string value. Path to a cab file.
;                  $sDirOut             - [optional] A string value. Extraction directory. Default is the same directory as the file in $sFileIn.
; Return values .: None
; Author ........: Achat
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: No
; ===============================================================================================================================
Func _Expand($sFileIn,$sDirOut=Default)
	If IsKeyword($sDirOut) Then $sDirOut=StringRegExpReplace($sFileIn,'(.*)\\.+$','\1')
	RunWait(@ComSpec & ' /c expand ' & Chr(34) & $sFileIn & Chr(34) &' /F:* /r '&Chr(34)&$sDirOut&Chr(34), @TempDir, @SW_HIDE)
EndFunc   ;==>_Expand
Bitte testen.

MfG