Results 1 to 2 of 2

Thread: Enumerate Files in .CAB File

Threaded View

  1. #1

    Thread Starter
    Frenzied Member dynamic_sysop's Avatar
    Join Date
    Jun 2003
    Location
    Ashby, Leicestershire.
    Posts
    1,142

    Post Enumerate Files in .CAB File

    Hi folks, long time since i done this
    anyway i've knocked together a little example that allows you to list the files in a .CAB file ( it can be built upon to allow extraction etc... )
    the class to read the cab ...
    VB Code:
    1. '/// at very top of Class / Form...
    2. Imports System.Runtime.InteropServices
    3.  
    4. Public Class CAB
    5. #Region "API / DELEGATES"
    6.     <StructLayout(LayoutKind.Sequential)> _
    7.     Public Structure FILE_IN_CABINET_INFO
    8.         Public NameInCabinet As IntPtr
    9.         Public FileSize As Int32
    10.         Public Win32Error As Int32
    11.         Public DosDate As Int16
    12.         Public DosTime As Int16
    13.         Public DosAttribs As Int16
    14.         <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=260)> _
    15.         Public FullTargetName As String
    16.     End Structure
    17.     Public Delegate Function PSP_FILE_CALLBACK_A(ByVal Context As Int32, ByVal Notification As Int32, ByVal Param1 As IntPtr, ByVal Param2 As IntPtr) As Int32
    18.     Private Declare Function SetupIterateCabinet Lib "setupapi.dll" Alias "SetupIterateCabinetA" (ByVal CabinetFile As String, ByVal Reserved As Int32, ByVal MsgHandler As PSP_FILE_CALLBACK_A, ByVal Context As Int32) As Int32
    19.     Private Declare Function DosDateTimeToFileTime Lib "kernel32.dll" (ByVal wFatDate As Int16, ByVal wFatTime As Int16, ByRef lpFileTime As FILETIME) As Int32
    20.     <StructLayout(LayoutKind.Sequential)> _
    21.     Private Structure FILETIME
    22.         '/// should be a Low & High part ( 2 x Int32 ) but 1 x Int64 works perfect with Date.FromFileTime
    23.         Public dwLowDateTime As Int64
    24.     End Structure
    25.     Private Const SPFILENOTIFY_CABINETINFO As Int32 = &H10
    26.     Private Const SPFILENOTIFY_FILEEXTRACTED As Int32 = &H13
    27.     Private Const SPFILENOTIFY_FILEINCABINET As Int32 = &H11
    28.     Private Const SPFILENOTIFY_NEEDNEWCABINET As Int32 = &H12
    29.     Private Const FILEOP_SKIP As Int32 = 2
    30. #End Region
    31.     '/// HERE i open a CAB file to read it's contents...
    32.     Public Sub New(ByVal cabpath As String)
    33.         Dim cb As New PSP_FILE_CALLBACK_A(AddressOf PSP_FILE_CALLBACK)
    34.         SetupIterateCabinet(cabpath, 0, cb, 0)
    35.     End Sub
    36.     Private Function PSP_FILE_CALLBACK(ByVal Context As Int32, ByVal Notification As Int32, ByVal Param1 As IntPtr, ByVal Param2 As IntPtr) As Int32
    37.         '/// from msdn's C++ description @ [url]http://msdn.microsoft.com/library/d...le_callback.asp[/url]
    38.         '/// my interpretation...
    39.         Dim FILEINCABINET As Int32 = 0
    40.         Select Case Notification
    41.             Case SPFILENOTIFY_FILEINCABINET
    42.                 '/// we've found a file in the CAB
    43.                 FILEINCABINET = PSP_FILEFOUND_CALLBACK(Context, Notification, Param1, Param2)
    44.                 '/// here we can also extract the files from the CAB.
    45.                 '/// but we'll call PSP_FILEFOUND_CALLBACK for now.
    46.         End Select
    47.         Return FILEINCABINET
    48.     End Function
    49.     Private Function PSP_FILEFOUND_CALLBACK(ByVal Context As Int32, ByVal Notification As Int32, ByVal Param1 As IntPtr, ByVal Param2 As IntPtr) As Int32
    50.         Dim FILEFOUND As Int32
    51.         Select Case Context
    52.             Case 0
    53.                 Dim f_in_cab As FILE_IN_CABINET_INFO = DirectCast(Marshal.PtrToStructure(Param1, GetType(FILE_IN_CABINET_INFO)), FILE_IN_CABINET_INFO)
    54.                 Dim frm As Form1 = DirectCast(Form.ActiveForm, Form1)
    55.                 '/// convert the IntPtr value of the filename to a readable string & add to a ListView...
    56.                 Dim lvi As New ListViewItem(Marshal.PtrToStringAnsi(f_in_cab.NameInCabinet))
    57.                 '/// the FILETIME should be 2 Int32's, but to get the resulting long value required i made it one Int64
    58.                 Dim ft As FILETIME
    59.                 DosDateTimeToFileTime(f_in_cab.DosDate, f_in_cab.DosTime, ft)
    60.                 Dim d As Date = Date.FromFileTime(ft.dwLowDateTime)
    61.                 lvi.SubItems.Add(New ListViewItem.ListViewSubItem(lvi, d.ToLongDateString & " " & d.ToLongTimeString))
    62.                 frm.ListView1.Items.Add(lvi)
    63.                 FILEFOUND = FILEOP_SKIP
    64.         End Select
    65.         '/// must Return FILEFOUND to continue enumerating the files in the cab.
    66.         Return FILEFOUND
    67.     End Function
    68. End Class
    the way to use it, from a Form ...
    VB Code:
    1. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    2.         Dim OD As New OpenFileDialog
    3.         With OD
    4.             .Filter = "CAB files|*.CAB"
    5.             .RestoreDirectory = True
    6.         End With
    7.         If OD.ShowDialog = DialogResult.OK Then
    8.             ListView1.Columns(0).Text = OD.FileName
    9.             Dim cabinet As New CAB(OD.FileName)
    10.         End If
    11.     End Sub
    i've included a zipped example source code
    Attached Files Attached Files
    ~
    if a post is resolved, please mark it as [Resolved]
    protected string get_Signature(){return Censored;}
    [vbcode][php] please use code tags when posting any code [/php][/vbcode]

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width