Create CAB Cabinet File
;======================================================================================================================
; Create CAB Cabinet File.
;
; CAB is the Microsoft Windows native compressed archive format.
; It supports compression and digital signing.
; Filename extension: .cab
; Internet media type: application/vnd.ms-cab-compressed
;
; Detlev Dalitz.20081024.
; Inspired by example code from Stan Littlefield April 32, 2007.
;======================================================================================================================

;----------------------------------------------------------------------------------------------------------------------
#DefineFunction udfPathSkipRoot (strPath)
If strPath == "" Then Return ""
objFSO = ObjectCreate ("Scripting.FileSystemObject")
intLen = StrLen (objFSO.GetDriveName (strPath)) ; Returns a string containing the name of the drive for a specified path.
If intLen > 0 Then strPath = StrSub (strPath, intLen + 1, -1) ; Remove DriveName from the path.
If StrScan (strPath, "\/", 1, @FWDSCAN) == 1 Then strPath = StrSub (strPath, 2, -1)
Return strPath
;......................................................................................................................
; Examples:
; "//SERVER/SHARE/FOLDER/FILE.EXT" ==> "FOLDER/FILE.EXT""
; "D:\FOLDER\FILE.EXT" ==> "FOLDER\FILE.EXT""
; "\FOLDER\FILE.EXT" ==> "FOLDER\FILE.EXT""
; DD.20081024.
;......................................................................................................................
#EndFunction
;----------------------------------------------------------------------------------------------------------------------

;----------------------------------------------------------------------------------------------------------------------
#DefineFunction udfAskFileName (strAFN_Title, strAFN_Folder, strAFN_Filetypes, strAFN_DefaultMask, intAFN_Flag)
Return AskFilename (strAFN_Title, strAFN_Folder, strAFN_Filetypes, strAFN_DefaultMask, intAFN_Flag)
:CANCEL
Return "" ; Return empty string if Dialog has been cancelled resp. closed by escape key.
#EndFunction
;----------------------------------------------------------------------------------------------------------------------


; Check for existance of MakeCab COM object application.
intLastErrorMode = ErrorMode (@OFF)
LastError ()
strProgId = "MakeCab.MakeCab.1"
objCab = ObjectCreate (strProgId)
ErrorMode (intLastErrorMode)
Terminate (LastError () > 0, "Terminated.", StrCat ("MakeCab", @LF, "COM object is not registered", @LF, strProgId))

; Select files to include in Cab file.
strFolder = DirScript ()
strFilenames = udfAskFileName ("Select files to include in Cabinet file", strFolder, "All files|*.*", "", 2)
Terminate (strFilenames == "", "Terminated.", StrCat ("MakeCab", @LF, "No files selected."))

; Define cab filename.
strFolder = DirScript ()
strFilenameDefault = "MyCabinetArchive.cab"
While @TRUE
   strCabFilename = udfAskFileName ("Save Cabinet file", strFolder, "Cabinet files|*.cab|All files|*.*", strFilenameDefault, 0)
   Terminate (strCabFilename == "", "Terminated.", StrCat ("MakeCab", @LF, "No cab filename selected."))
   If StrLower (FileExtension (strCabFilename)) == "cab" Then Break
   ; Message ("MakeCab", `Cab filename must have extension ".cab"`)
   strFilenameDefault = StrCat (strCabFilename, ".cab")
EndWhile

blnCabSaveFolderTree = @TRUE
blnCabSaveFolderTree = @FALSE

; Create cab file.
; objCab.CreateCab (CabFileName, MakeSignable, ExtraSpace, Use10Format)
; objCab.AddFile (FileName, FileNameInCab)
objCab.CreateCab (strCabFilename, ObjectType ("BOOL", @FALSE), 0, ObjectType ("BOOL", @FALSE))
While strFilenames != ""
   strFilename = ItemExtract (1, strFilenames, @TAB)
   strFilenames = ItemRemove (1, strFilenames, @TAB)
   If blnCabSaveFolderTree
      strFilenameInCab = udfPathSkipRoot (strFilename) ; Cabinet archive with tree folder structure without root.
   Else
      strFileNameInCab = FileBaseName (strFilename)    ; Cabinet archive with one flat folder.
   EndIf
   objCab.AddFile (strFilename, strFilenameInCab)
EndWhile
objCab.CloseCab ()
objCab = 0

Terminate (FileExist (strCabFilename) == 0, "Terminated.", StrCat ("MakeCab", @LF, "Cannot create file", @LF, strCabFilename))

Run (strCabFilename, "") ; Open cab file with associated cab file viewer.

Exit