Cab-Datei entpacken

  • Hi,
    ich versuche eine cab-Datei zu entpacken.
    Mit der Suche im deutschen und englischen Forum habe ich zwar eine Funktion gefunden.
    Aber irgendwie funktioniert die nicht.
    Habt ihr ne Idee

    Spoiler anzeigen
    [autoit]

    #include<File.au3>
    InetGet("http://go.microsoft.com/fwlink/?LinkID=39204", "C:\test.cab", 1, 0)

    [/autoit] [autoit][/autoit] [autoit]

    _CabExtract("C:\test.cab", "C:\");, -1, -1, '*.*')

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

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

    [/autoit] [autoit][/autoit] [autoit]

    ; 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
    ;===================================================================================================

    [/autoit] [autoit][/autoit] [autoit]

    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

    [/autoit] [autoit][/autoit] [autoit]

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

    [/autoit] [autoit][/autoit] [autoit]

    ; 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
    ;===================================================================================================

    [/autoit] [autoit][/autoit] [autoit]

    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

    [/autoit] [autoit][/autoit] [autoit]

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

    [/autoit] [autoit][/autoit] [autoit]

    ; 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
    ;===================================================================================================

    [/autoit] [autoit][/autoit] [autoit]

    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

    [/autoit] [autoit][/autoit] [autoit]

    ; 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

    [/autoit] [autoit][/autoit] [autoit]

    ;;;;;;;;; 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

    [/autoit]
  • verwende doch einfach das Windows eigene "expand" dazu.
    ein kleines Script und ...

    MfG Schnuffel

    "Sarkasmus ist die niedrigste Form des Witzes, aber die höchste Form der Intelligenz."
    Val McDermid

    ein paar Infos ...

    Wer mehr als "nur" Hilfe benötigt, kann sich gern im Forum "Programmieranfragen" an uns wenden. Wir helfen in allen Fällen, die die Forenregeln zulassen.

    Für schnelle Hilfe benötigen wir ein ! lauffähiges ! Script, dass wir als Demonstration des Problems testen können. Wer von uns erwartet ein Teilscript erstmal lauffähig zu bekommen, der hat
    1. keine wirkliche Not
    2. keinen Respekt vor Menschen die ihm in ihrer Freizeit Ihre Hilfe anbieten
    3. oder ist einfach nur faul und meint wir coden das für ihn

    In solchen Fällen erlaube ich mir, die Anfrage einfach zu ignorieren. ;)

  • @DerDoc
    jetzt sag aber nich, du schreibst ein Script,
    dass Deinen TotalCommander steuert, um die .cab zu extrahieren :rofl:

    sorry, der musste sein :rolleyes:

    MfG Schnuffel

    "Sarkasmus ist die niedrigste Form des Witzes, aber die höchste Form der Intelligenz."
    Val McDermid

    ein paar Infos ...

    Wer mehr als "nur" Hilfe benötigt, kann sich gern im Forum "Programmieranfragen" an uns wenden. Wir helfen in allen Fällen, die die Forenregeln zulassen.

    Für schnelle Hilfe benötigen wir ein ! lauffähiges ! Script, dass wir als Demonstration des Problems testen können. Wer von uns erwartet ein Teilscript erstmal lauffähig zu bekommen, der hat
    1. keine wirkliche Not
    2. keinen Respekt vor Menschen die ihm in ihrer Freizeit Ihre Hilfe anbieten
    3. oder ist einfach nur faul und meint wir coden das für ihn

    In solchen Fällen erlaube ich mir, die Anfrage einfach zu ignorieren. ;)