View and Extract CAB File Contents Programmatically

Cabinet (.CAB) files are used to store one or more files in a compressed format. They are similar to ZIP (.ZIP) files with a slight twist. ZIP files contain one or more individually compressed files. Thus, a ZIP file is much smaller than the original file(s). A CAB file can compress files across file boundaries and can often achive a better compression ratio.

That's great but how do you work with CAB files? To create a CAB file you must use the MakeCab.exe program that comes with VB. This program is documented in MSDN (see my Microsoft Links page) and not discussed here. This page talks about viewing and extracting the contents of a CAB file which you can do programmatically with the SetupIterateCabinet API.

View and extract cabinet file contents
Download Source Code

Discussion

The core logic in this sample is contained in a class module that you can easily incorporate into your project. The SetupIterateCabinet function iterates through all the files in a cabinet and sends a notification to a callback function in your code for each file found. Since callback procedures must reside in a standard module, this program includes a .BAS module you will need to add to your project as well.

The class itself provides several useful methods, properties and events as show.

Name

Type

Description

CabName

Property

Name of the cabinet to process.

FileCount

Property

Number of files in the cabinet.

Extract

Method

Extracts and decompresses the file(s) from the cabinet. You specify a file to extract. All files are extracted by default. You can indicate the folder to extract to. The default is the same folder as the cab file. When extracting a single file, you can specify the extract file name. The default is the original file name.

GetInfo

Method

Gets the name size and date of each file in the cabinet.

GetXML

Method

Returns a well-formed XML string containing the name, size and date of each file in the cabinet.

AfterExtract

Event

Raised, by the Extract method, after a file is extracted and passes as a paramter the extracted file's name.

BeforeExtract

Event

Raised, by the Extract method, before a file is extracted and passes as paramters the name of the file to extract and a flag that can be used to cancel the extraction.

FileFound

Event

Raised as a file is found within the cabinet by the GetInfo method.

Since the class module raises events back to the caller, the variable used to reference an instance of the class must be declared using the WithEvents keyword. This allows the class' event procedures to be displayed in the procedure dropdown when the variable is selected in the object dropdown in the code edit window.

To call the SetupIterateCabinet function you need to specify four values: the path to your CAB file, a zero for the second, reserved parameter, your callback function's address, and a context indicator value. This value is used to tell the callback function what to do. SetupIterateCabinet returns a non-zero value upon success. If it fails you can use Err.LastDLLError to see why.

Callback functions must reside in a .BAS module. However, to make this class more self contained, the callback function in the .BAS module, CabinetCallback, simply calls a similarly named method in the class passing along all the parameters populated by SetupIterateCabinet. The address of the .BAS module's CabinetCallback procedure is passed into the API using the AddressOf keyword. However, for the real callback function to find the callback method, the class must call a procedure in the .BAS module and pass in a reference to the class.

The context indicator value passed into the API can be any integer value you like. It is simply returned by SetupIterateCabinet to your callback procedure as a parameter. Thus, your callback procedure will know why SetupIterateCabinet was called to begin with and how it should proceed. In this program the allowable context values are defined in the SetupIterateCabinetActions enumeration.

Your callback function must be defined with four arguments. The first is a long that returns your context indicator value. The second is the notification message returned by SetupIterateCabinet. Parameter three is a long that will hold the address of a structure describing the file being extracted or the file found in the cabinet. The type of this structure varies depending on the notification message. It can be either of type FILEPATHS or FILEINCABINETINFO. The last parameter also varies based on the notification.

Notification

Description

SPFILENOTIFY_FILEEXTRACTED

A file was extracted from the cabinet. Param3 is a FILEPATHS structure with info on the extracted file. The callback function must return NO_ERROR if you want to keep procesesing or non-zero to stop.

SPFILENOTIFY_FILEINCABINET

A file was found in the cabinet. Param3 is a FILE_IN_CABINET_INFO structure describing the current file. Return FILEOP_SKIP to skip the file or FILEOP_DOIT to extract it.

SPFILENOTIFY_NEEDNEWCABINET

The file being extracted is continued in the next cabinet. This is not handled in this program. You would need to prompt for the next file or diskette,... (see MSDN for SetupPromptForDisk) Param3 is a CABINETINFO structure. The callback function must return NO_ERROR if you want to keep procesesing or non-zero to stop.

Things get confusing with parameter 3 of the callback function pointing to different types of structures depending on the notification. To simplify this, the parameter is defined as a FileInCabinetInfo structure and passed by reference. This is the type of structure returned most often by the SetupIterateCabinet API in this program. Doing this lets VB take the bytes at that address and show them to you as a FileInCabinetInfo user defined type.

In the cases where the notification message returns a different type of structure, the VB LSet function is used to copy the bytes in the FileInCabinetInfo structure to the appropriate structure.

The last parameter of the callback function is a long which often contains the address of a string, such as the file name being processed. This address must be converted to a real string for VB to work with it. A call to the CopyMemory API achieves this.

Each method and property in the class performs the same four basic steps. They insure the cabinet file's name is set, call SetCabFile in the .BAS module to set a reference to the class module so the fake callback function can call the real callback method, call the SetupIterateCabinet API with the appropriate parameters, and finally, check the return value from the API.

Instructions

Run the program and click the Browse button to navigate to the .Cab file to view. Once a cabinet file is selected, use the mouse and Shift or Control keys to highlight one or more files. Then click the Extract button. On the subsequent dialog box, navigate to the folder to extract the file(s) to and press Extract.

Also, once you have selected a .cab file, you can press the XML List button to display an XML string representing the contents of the cab file.




About TheScarms
About TheScarms


Sample code
version info

If you use this code, please mention "www.TheScarms.com"

Email this page


© Copyright 2024 TheScarms
Goto top of page