Extract CAB files with Python and Patool.

Install 7zip.

This assumes you are on Windows.

Add the 7zip path to the system path. In the searchbar type env and open the result. Click Environment Variables in the dialog. Add to PATH. Windows 10 just click add and browse to the folder 7zip installed to, i.e., C:\Program Files\7-zip. Otherwise, paste the path making sure it’s at the end of the line followed by a ;

With Python installed, I use 3.7, open the terminal. In the searchbar type cmd and open the result. In the terminal type: pip install patool

You are all set. The only thing I found, and this is likely to do with 7zip, is when extracting many CABS to a single destination it hangs. I did not test this using 7z.exe directly. Just create a folder for each CAB you extract and move the extracted files to a single folder.

Here’s one I wrote to extract all the crap in DirectX9 from MS separated by 32/64 bit.

#!/usr/bin/python3
import os
import shutil
import patoolib

def unpack_cabs(source,dest,extract=True):
    if not os.path.exists(dest):
        os.mkdir(dest)
        
    prg = patoolib.find_archive_program(('cab'), 'extract', program=r'C:\Program Files\7-Zip\7z.exe')
    if extract:
        for cab in os.listdir(source):
            cab = cab.strip().lower()
            if not cab.endswith('.cab'): continue
            sub_folder = os.path.join(dest,cab.split('.')[0])
            if not os.path.exists(sub_folder):
                os.mkdir(sub_folder)

            full_source = os.path.join(source.lower(),cab)
            print('extracting %s' % sub_folder) 
            patoolib.extract_archive(full_source, outdir=sub_folder, program=prg)
            
    tmpx86 = os.path.join(dest,'tmp', 'x86')
    tmpx64 = os.path.join(dest,'tmp', 'x64')
    if not os.path.exists(tmpx86):
        os.makedirs(tmpx86)
    if not os.path.exists(tmpx64):
        os.makedirs(tmpx64)
    
    arch={'x86':{},'x64':{}}
    filter = ['x3d','d3d','xau','xin','xact','xapo']
    for exfolder in os.listdir(dest):
        
        if 'tmp' in exfolder: continue
        
        d_type = exfolder.split('_')[-1]
        
        subs = os.path.join(dest,exfolder)
        
        for dll in os.listdir(subs):
            dll = dll.strip().lower()
            fname = dll.split('.')[0]
            if not dll.endswith('.dll'): continue
            if dll[:3] not in filter: continue

            if d_type == 'x86':
                print(d_type, os.path.join(subs.lower(),dll),'->',os.path.join(tmpx86.lower(),dll))
                shutil.copyfile(os.path.join(subs.lower(),dll),os.path.join(tmpx86.lower(),dll))
                if fname not in arch[d_type]:
                    arch[d_type][fname] = None
            
                arch[d_type][fname] = os.path.join(tmpx64.lower(),dll)

            if d_type == 'x64':
                print(d_type, os.path.join(subs.lower(),dll),'->',os.path.join(tmpx64.lower(),dll))
                shutil.copyfile(os.path.join(subs.lower(),dll),os.path.join(tmpx64.lower(),dll))
                if fname not in arch[d_type]:
                    arch[d_type][fname] = None
            
                arch[d_type][fname] = os.path.join(tmpx64.lower(),dll)
    return arch

~ by mohawke on December 21, 2018.