Jump to content
Sign in to follow this  
jben

Opening cab file with AutoIT

Recommended Posts

jben

Sorry if this sounds silly but can AutoIT open .cab files. I'm new to cab files but trying to compress my data a little...

I'm wondering if I have an setup.exe with data files in a .cab file then will AutoIT still be able to open the exe?

thanks

Share this post


Link to post
Share on other sites
redsleeves

Cabinet.dll in the system directory?

Share this post


Link to post
Share on other sites
ivan

I wrote this a long time ago so i don't really remember how it works, hope it helps

#include <Array.au3>
;===================================================================================================



#include <Array.au3>
#include <File.au3>

;===================================================================================================


; Function Name:    _MakeDff()
; Description:      Create a dff file containing the directives to create a cabinet.
; Remarks:          To create a *.cab, a dff file containing the directives must be create. Such file
;                   contains information about how the cabinet is to be built (i.e., cabinet file name, the
;                   directory where the dff is to be stored, the target media (floppy, cdrom, etc) and maximum
;                   file size, etc.) as well as a list of files to store in the cabinet.
; Usage:            1.-The $pFiles parameter can either be a 1Dim array with each element containing a full path
;                   to a file, or a path to a directory, or to a single file. If $pExtis an array, try to
;                   group files according to their type to help compression. If $pExt is a path to a directory,
;                   you can use the $pExtto specify file types, wildcards allowed.
;                   2.-You may modify the settings that define the directives for the dff with the $pSettings
;                   parameter, substituting the default values.
; Parameter(s):     $pDffFile       - Compulsory:   FileName for dff file
;                   $pFiles         - Compulsory:   Files array or path to directory
;                   $pCabDirName    - Compulsory:   Subdirectory of $pDffDest where
;                                                   the cabinet will be stored
;                   $pCabName       - Compulsory:   Name for the cabinet file
;                   $pDffDest       - Optional:     Path to $pDffFile
;                                       -1      =   (Default) Current directory
;                                       String  =   path to output directory, no trailing slash. If the directory
;                                                   doesn't already exist, the script will attempt to create it.
;                   $pFileIndex     - Optional:     specifies index to start logging the $pFiles array
;                                       1       =   (Default) start with element 1 of the $pFiles array
;                   $pSettings      - Optional:     Directives for the dff file, see the $lSettings array
;                                       -1      =   (Default) directives as set in the $lSettings array
;                                       if modified, make sure your directives start at element 1 of the array
;                   $pExt           - Optional:     Specifies filetypes in $pFiles directory to be included in the dff,
;                                                   only relevant if $pFiles is a path pointing to a directory.
;                                                   WildCards allowed i.e, *.* or *.h?ml, etc.
; Requirement(s):   AutoIt3 V3.2 or higher
; Return Value(s):  On Success  - returns 1 and createsthe file
;                  On Failure   - Returns 0 and sets @ERROR
;                   @ERROR          = 1 Invalid Parameters, see extended
;                                   @Extended   =   1 when not using default $pDffDest and dff destination dir is not a string
;                                               =   2 when not using default $pDffDest and dff destination dir could not be created
;                                               =   3 dff file is invalid or already exists
;                                               =   4 $pCabDirName is not a valid directory name
;                                               =   5 $pCabName already exists or is not a valid filename
;                                               =   6 wrong type for $pFiles (neither array nor string)
;                                               =   7 invalid $pSettings neither array nor default value=-1
;                                               =   8 invalid $pFileIndex in $pFiles array
;                   @ERROR          = 2 $pFiles array error
;                                   @Extended   =   1 unable to generate files in $pFiles dir
;                   @ERROR          = 3 file in $pFiles array error
;                                   @Extended   =   1 file in $pFiles array does not exist
; NOTE:             Subdirectories are omitted from cabinet when $pFiles is a path to a directory
; TODO:             CHECK $pExt for errors
; Date:             11/9/2007
; Author:           Ivan Perez
;===================================================================================================


Func _MakeDff($pDffFile, $pFiles, $pCabDirName, $pCabName, $pDffDest = -1, $pFileIndex = 1, $pSettings = -1, $pExt = '*.*')
    Local $lFileAttr, $lDff, $lFileSearch, $lFileFound, $lDffHndl
    Dim $lFileList[1] = [0], $lFileArr[1] = [0], $lSettings[19]
    $lSettings[0] = 19
    $lSettings[1] = '.OPTION EXPLICIT'
    $lSettings[2] = '.Set InfDiskHeader="[disk list]"'
    $lSettings[3] = '.Set InfDiskHeader1=";<disk number>,<disk label>"'
    $lSettings[4] = '.Set InfDiskLineFormat="*disk#*,*label*"'
    $lSettings[5] = '.Set InfCabinetHeader="[cabinet list]"'
    $lSettings[6] = '.Set InfCabinetHeader1=";<cabinet number>,<disk number>,<cabinet file name>"'
    $lSettings[7] = '.Set InfCabinetLineFormat="*cab#*,*disk#*,*cabfile*"'
    $lSettings[8] = '.Set InfFileHeader=";*** File List ***"'
    $lSettings[9] = '.Set InfFileHeader1=";<disk number>,<cabinet number>,<filename>,<size>"'
    $lSettings[10] = '.Set InfFileHeader2=";Note: File is not in a cabinet if cab# is 0"'
    $lSettings[11] = '.Set InfFileHeader3=""'
    $lSettings[12] = '.Set InfFileLineFormat="*disk#*,*cab#*,*file*,*date*,*size*"'
    $lSettings[13] = '.Set GenerateInf=ON'
    $lSettings[14] = '.Set Compress=ON'
    $lSettings[15] = '.Set Cabinet=ON'
    $lSettings[16] = '.Set CompressionType=MSZIP'
    $lSettings[17] = '.Set DiskDirectoryTemplate=CDROM'
    $lSettings[18] = '.Set MaxDiskSize=CDROM'
    
; valid dff destination
    If $pDffDest <> -1 Then
        If Not IsString($pDffDest) Then
            SetError(1, 1, 0)
            Return
        EndIf
        If Not FileExists($pDffDest) Then DirCreate($pDffDest)
        If Not FileExists($pDffDest) Or Not StringInStr(FileGetAttrib($pDffDest), 'D') Then
            SetError(1, 2, 0)
            Return
        EndIf
    Else
        $pDffDest = @ScriptDir
    EndIf
    
; $pDffFile: valid filename and not exist
    If Not _IsValidFileName($pDffFile) Or FileExists($pDffDest & '\' & $pDffFile) Then
        SetError(1, 3, 0)
        Return
    EndIf
    
; check $pCabDirName
    If Not _IsValidFileName($pCabDirName) Then
        SetError(1, 4, 0)
        Return
    EndIf
; check $pCabName
    If Not _IsValidFileName($pCabName) Or FileExists($pDffDest & '\' & $pCabDirName & '\' & $pCabName) Then
        SetError(1, 5, 0)
        Return
    EndIf
    
; check type on parm $pFiles
    If Not (IsArray($pFiles) Or IsString($pFiles)) Then
        SetError(1, 6, 0)
        Return
    EndIf
    
; validate $pSettings
    If IsArray($pSettings) Then
        $lSettings = $pSettings
    ElseIf $pSettings <> -1 Then
        SetError(1, 7, 0)
        Return
    EndIf
    ReDim $lSettings[UBound($lSettings) + 1]
    $lSettings[UBound($lSettings) - 1] = '.Set DiskDirectory1=' & $pCabDirName
    ReDim $lSettings[UBound($lSettings) + 1]
    $lSettings[UBound($lSettings) - 1] = '.Set CabinetNameTemplate=' & $pCabName
    
; define $lFileList or set $pFiles array
    If IsString($pFiles) Then
    ; files exist
        If FileExists($pFiles) Then
        ; Just assign
            If Not StringInStr(FileGetAttrib($pFiles), 'D') Then
                ReDim $lFileList [UBound($lFileList) + 1]
                $lFileList[UBound($lFileList) - 1] = '"' & $pFiles & '"'
            ; build files in directory
            Else
                $lFileSearch = FileFindFirstFile($pFiles & '\' & $pExt)
                If $lFileSearch = -1 Then
                    SetError(2, 1, 0)
                    Return
                EndIf
                While 1
                    $lFileFound = FileFindNextFile($lFileSearch)
                    If @error Then ExitLoop
                    If FileExists($pFiles & '\' & $lFileFound) And Not StringInStr(FileGetAttrib($lFileFound), 'D') Then
                        ReDim $lFileArr[UBound($lFileArr) + 1]
                        $lFileArr[UBound($lFileArr) - 1] = $pFiles & '\' & $lFileFound
                    EndIf
                WEnd
                $lFileArr[0] = UBound($lFileArr) - 1
                FileClose($lFileSearch)
            ; reset for array procedure
                $pFiles = $lFileArr
                $pFileIndex = 1
            EndIf
        EndIf
    EndIf
; define $lFileList from $pFiles array
    If IsArray($pFiles) Then
    ; valid index on array
        If Not IsInt($pFileIndex) And $pFileIndex < 0 And $pFileIndex < UBound($pFiles) Then
            SetError(1, 8, 0)
            Return
        EndIf
    ; files exist
        For $i = $pFileIndex To UBound($pFiles) - 1 Step 1
            $lFileAttr = FileGetAttrib($pFiles[$i])
            If FileExists($pFiles[$i]) = 1 Then
                If Not StringInStr($lFileAttr, 'D') Then
                    ReDim $lFileList [UBound($lFileList) + 1]
                    $lFileList[UBound($lFileList) - 1] = '"' & $pFiles[$i] & '"';& @CRLF
                EndIf
            Else
                SetError(3, 1, 0)
                Return
            EndIf
        Next
        $lFileList[0] = UBound($lFileList) - 1
    EndIf
    
; build the text for the dff file
    $lDffHndl = FileOpen($pDffDest & '\' & $pDffFile, 2)
    For $i = 1 To UBound($lSettings) - 1 Step 1
        FileWriteLine($lDffHndl, $lSettings[$i])
    Next
    For $i = 1 To UBound($lFileList) - 1 Step 1
        FileWriteLine($lDffHndl, $lFileList[$i])
    Next
    FileClose($lDffHndl)
    Return 1
EndFunc  ;==>_MakeDff

;===================================================================================================


; Function Name:    _MakeCab()
; Description:      Create a cabinet file from a previously created (manually or with _MakeDff) dff file.
; Parameter(s):     $pDffFile       - Compulsory:   FileName of dff file
;                   $pDffPath       - Compulsory:   Path to $pDffFile
;                   $pCabDest       - Compulsory:   Path to cabinet directory
; Return Value(s):  On Success  - returns 1 and creates the cabinet file
;                  On Failure   - Returns 0 and sets @ERROR
;                   @ERROR          = 1 Invalid Parameters, see extended
;                                   @Extended   =   1 invalid $pDffFile or doesn't exist
;                                               =   2 invalid $pDffPath or doesn't exist
;                                               =   3 Cabinet dir couldn't be created
; Requirement(s):   AutoIt3 V3.2 or higher
; NOTE: Subdirectories are omitted from cabinet when $pFiles is a path to a directory
; Date:             9/9/2007
; Author:           Ivan Perez
;===================================================================================================


Func _MakeCab($pDffFile, $pDffPath, $pCabDest)
    Local $lCmd, $lWorkingDir, $lResult
; validate path to dff file
    If Not FileExists($pDffPath) Or Not StringInStr(FileGetAttrib($pDffPath), 'D') Then
        SetError(1, 1, 0)
        Return
    EndIf
; validate $pDffFile
    If Not (_IsValidFileName($pDffFile) Or FileExists($pDffPath & '\' & $pDffFile)) Then
        SetError(1, 2, 0)
        Return
    EndIf
; validate cabinet directory
    If Not FileExists($pCabDest) Then DirCreate($pCabDest)
    If Not FileExists($pCabDest) Or Not StringInStr(FileGetAttrib($pCabDest), 'D') Then
        SetError(1, 3, 0)
        Return
    EndIf
; create the command
    $lCmd = 'makecab  /F ' & '"' & $pDffPath & '\' & $pDffFile & '"'
; run the command
    $lResult = RunWait(@ComSpec & " /c " & $lCmd, $pCabDest, @SW_HIDE)
; delete the files created by makecab
    If FileExists($pCabDest &'\' &'setup.inf') Then FileDelete($pCabDest &'\' &'setup.inf')
    If FileExists($pCabDest &'\' &'setup.rpt') Then FileDelete($pCabDest &'\' &'setup.rpt')
    If $lResult = 0 Then Return 1
    Return 0
EndFunc  ;==>_MakeCab

;===================================================================================================


; Function Name:    _CabGetFiles()
; Description:      Generate a list of files in cabinet.
; Parameter(s):     $pCabFile       - Compulsory:   FileName of cabinet file
;                   $pDestDir       - Compulsory:   Path to $pCabFile
;                                       -1      =   (Default) Working directory
;                                       String  =   path to output directory, no trailing slash. If the directory
;                                                   doesn't already exist, the script will attempt to create it.
; Requirement(s):   AutoIt3 V3.2 or higher
; Return Value(s):  On Success  - returns 1 and creates the file
;                  On Failure   - Returns 0 and sets @ERROR
;                   @ERROR          = 1 Invalid Parameters, see extended
;                                   @Extended   =   1 when not using default $pDffDest and dff destination dir is not a string
;                                               =   2 when not using default $pDffDest and dff destination dir could not be created
;                                               =   3 dff file is invalid or already exists
; NOTE: Subdirectories are omitted from cabinet when $pFiles is a path to a directory
; TODO:             CHECK result (run exit code?)
; Date:             9/9/2007
; Author:           Ivan Perez
;===================================================================================================


Func _CabGetFiles($pCabFile, $pCabPath = -1)
    Local $lCmd, $lWorkingDir, $lResult, $lTmp, $lReadFileHndl, $lFile
    Dim $lFileArr[1] = [0]
    If $pCabPath <> -1 Then
        If Not IsString($pCabPath) Then
            SetError(1, 1, 0)
            Return
        EndIf
        If Not FileExists($pCabPath) Then DirCreate($pCabPath)
        If Not FileExists($pCabPath) Or Not StringInStr(FileGetAttrib($pCabPath), 'D') Then
            SetError(1, 2, 0)
            Return
        EndIf
    Else
        $pCabPath = @ScriptDir
    EndIf
; $pCabFile: valid filename and not exist
    If Not (_IsValidFileName($pCabFile) Or FileExists($pCabPath & '\' & $pCabFile)) Then
        SetError(1, 3, 0)
        Return
    EndIf
; create tmp file
    $lTmp = _TempFile($pCabPath)
    
    If IsNumber($pCabPath) And $pCabPath = 0 Then
        $lCmd = 'expand -D ' & '"' & $pCabFile & '"'
        $lWorkingDir = ''
    Else
        $lCmd = 'expand -D ' & '"' & $pCabPath & '\' & $pCabFile & '"'
        $lWorkingDir = $pCabPath
    EndIf
    $lCmd &= '>"'&$lTmp & '"'
; run the command to dump the file list to tmp file
    $lResult = RunWait(@ComSpec & " /c " & $lCmd, $lWorkingDir, @SW_HIDE)
    If $lResult = 0 And FileExists($lTmp) Then
    ; read file contents
        $lReadFileHndl = FileOpen($lTmp, 0)
        While 1
            $lLine = FileReadLine($lReadFileHndl)
            If @error = -1 Then ExitLoop; EOF
            $lFile = StringReplace($lLine, $pCabFile & ': ', '')
            If @extended > 0 Then
                ReDim $lFileArr[UBound($lFileArr) + 1]
                $lFileArr[UBound($lFileArr) - 1] = $lFile
            EndIf
        WEnd
        FileClose($lReadFileHndl)
        $lFileArr[0] = UBound($lFileArr) - 1
;~      If FileExists($lWorkingDir &'\' &$lTmp) Then FileDelete($lWorkingDir &'\' &$lTmp)
        FileDelete($lTmp)
        If FileExists($lTmp) Then MsgBox(0,'Tmp not deleted',$lTmp)
    Else
    ; file list could not be dumped
        SetError(2, 1, 0)
        Return
    EndIf
    Return $lFileArr
EndFunc  ;==>_CabGetFiles

; extract files to a directory
;~ Func _CabExtract($pCabFile, $pDest, $pCabPath = -1, $pMode = -1, $pFileList = -1, $pExt = '*.*')
Func _CabExtract($pCabFile, $pDest, $pCabPath = -1, $pMode = -1, $pExt = '*.*')
    Local $lCmd, $lCommand, $lWorkingDir, $lResult, $lTmp, $lReadFileHndl, $lFile
    Local $lFileList
    Dim $lFileArr[1] = [0], $lPaths[5]
    If $pCabPath <> -1 Then
        If Not IsString($pCabPath) Then
            SetError(1, 1, 0)
            Return
        EndIf
        If Not FileExists($pCabPath) Then DirCreate($pCabPath)
        If Not FileExists($pCabPath) Or Not StringInStr(FileGetAttrib($pCabPath), 'D') Then
            SetError(1, 2, 0)
            Return
        EndIf
    Else
        $pCabPath = @ScriptDir
    EndIf
; $pCabFile: valid filename and not exist
    If Not (_IsValidFileName($pCabFile) Or FileExists($pCabPath & '\' & $pCabFile)) Then
        SetError(1, 3, 0)
        Return
    EndIf
    
; $pCabFile: valid filename and not exist
    If Not FileExists($pDest) Then DirCreate($pDest)
    If Not FileExists($pDest) Or Not StringInStr(FileGetAttrib($pDest), 'D') Then
        SetError(1, 4, 0)
        Return
    EndIf
    
    If Not IsNumber($pMode) Or ($pMode < -1 And $pMode > 0) Then
        SetError(1, 5, 0)
        Return
    EndIf
    
    $lFileList = _CabGetFiles($pCabFile, $pCabPath)
    If @error Or Not IsArray($lFileList) Then
        SetError(1, 6, 0)
        Return
    EndIf
    If UBound($lFileList) - 1 = 1 Then; single file extraction
        $lPaths = _PathSplit($lFileList[1], $lPaths[0], $lPaths[1], $lPaths[2], $lPaths[3])
        $lCmd = 'expand ' & '"' & $pCabPath & '\' & $pCabFile & '" ' & '"' & $pDest & '\' & $lPaths[3] & $lPaths[4] & '"'
    ElseIf UBound($lFileList) - 1 > 1 Then; multiple file extraction
        Switch $pMode
        ; extract all
            Case - 1
                $lCmd = 'expand ' & '"' & $pCabPath & '\' & $pCabFile & '" -F:* ' & '"' & $pDest & '"'
            ; extract selected file types
            Case 0
                $lCmd = 'expand ' & '"' & $pCabPath & '\' & $pCabFile & '" -F:' & $pExt & ' ' & '"' & $pDest & '"'
        EndSwitch
    Else
        SetError(2, 1, 0)
        Return
    EndIf
    $lResult = RunWait(@ComSpec & " /c " & $lCmd, $lWorkingDir, @SW_HIDE)
    If $lResult <> 0 Then
        SetError(2, 1, 0)
        Return
    EndIf
    Return 1
EndFunc  ;==>_CabExtract

;;;;;;;;; support funcs
; won't accept filenames containing chr(0) or chr(127)
Func _IsValidFileName($pFileName)
    If StringRegExp($pFileName, '(["*/<>?\\|]|[[:cntrl:]])', 0) Then Return 0; ascii 0-31
    Return 1
EndFunc  ;==>_IsValidFileName

use function _CabExtract

Edited by ivan

Share this post


Link to post
Share on other sites
ptrex

@all

Maybe this can get you going.

WindowsUnZip("C:\Test.CAB","C:\Temp")

Func WindowsUnZip($sUnzipFileName, $sUnzipDestination)
$oUnzipFSO = ObjCreate("Scripting.FileSystemObject")    
  If Not $oUnzipFSO.FolderExists($sUnzipDestination) Then
    $oUnzipFSO.CreateFolder($sUnzipDestination)
  EndIf

$WshShell = ObjCreate("Shell.Application")
  With $WshShell
       .NameSpace($sUnzipDestination).Copyhere (.NameSpace($sUnzipFileName).Items)
  EndWith
EndFunc

Regards,

ptrex

Share this post


Link to post
Share on other sites
ptrex

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×