dynamic_sysop
Well-known member
Hi folks, long time since i done this [Broken External Image]:http://www.computerhelp.forum/x_images/images/smilies/frown.gif
anyway ive 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 ...
the way to use it, from a Form ...
ive included a zipped example source code [Broken External Image]:http://www.computerhelp.forum/x_images/images/smilies/smile.gif
anyway ive 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 ...
Code:
/// at very top of Class / Form...
Imports System.Runtime.InteropServices
Public Class CAB
#Region "API / DELEGATES"
<StructLayout(LayoutKind.Sequential)> _
Public Structure FILE_IN_CABINET_INFO
Public NameInCabinet As IntPtr
Public FileSize As Int32
Public Win32Error As Int32
Public DosDate As Int16
Public DosTime As Int16
Public DosAttribs As Int16
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=260)> _
Public FullTargetName As String
End Structure
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
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
Private Declare Function DosDateTimeToFileTime Lib "kernel32.dll" (ByVal wFatDate As Int16, ByVal wFatTime As Int16, ByRef lpFileTime As FILETIME) As Int32
<StructLayout(LayoutKind.Sequential)> _
Private Structure FILETIME
/// should be a Low & High part ( 2 x Int32 ) but 1 x Int64 works perfect with Date.FromFileTime
Public dwLowDateTime As Int64
End Structure
Private Const SPFILENOTIFY_CABINETINFO As Int32 = &H10
Private Const SPFILENOTIFY_FILEEXTRACTED As Int32 = &H13
Private Const SPFILENOTIFY_FILEINCABINET As Int32 = &H11
Private Const SPFILENOTIFY_NEEDNEWCABINET As Int32 = &H12
Private Const FILEOP_SKIP As Int32 = 2
#End Region
/// HERE i open a CAB file to read its contents...
Public Sub New(ByVal cabpath As String)
Dim cb As New PSP_FILE_CALLBACK_A(AddressOf PSP_FILE_CALLBACK)
SetupIterateCabinet(cabpath, 0, cb, 0)
End Sub
Private Function PSP_FILE_CALLBACK(ByVal Context As Int32, ByVal Notification As Int32, ByVal Param1 As IntPtr, ByVal Param2 As IntPtr) As Int32
/// from msdns C++ description @ [url="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/setupapi/setup/psp_file_callback.asp"]http://msdn.microsoft.com/library/default.asp?url=/library/en-us/setupapi/setup/psp_file_callback.asp[/url]
/// my interpretation...
Dim FILEINCABINET As Int32 = 0
Select Case Notification
Case SPFILENOTIFY_FILEINCABINET
/// weve found a file in the CAB [b][Broken External Image][/b]:[URL]http://www.computerhelp.forum/x_images/images/smilies/smile.gif[/URL]
FILEINCABINET = PSP_FILEFOUND_CALLBACK(Context, Notification, Param1, Param2)
/// here we can also extract the files from the CAB.
/// but well call PSP_FILEFOUND_CALLBACK for now.
End Select
Return FILEINCABINET
End Function
Private Function PSP_FILEFOUND_CALLBACK(ByVal Context As Int32, ByVal Notification As Int32, ByVal Param1 As IntPtr, ByVal Param2 As IntPtr) As Int32
Dim FILEFOUND As Int32
Select Case Context
Case 0
Dim f_in_cab As FILE_IN_CABINET_INFO = DirectCast(Marshal.PtrToStructure(Param1, GetType(FILE_IN_CABINET_INFO)), FILE_IN_CABINET_INFO)
Dim frm As Form1 = DirectCast(Form.ActiveForm, Form1)
/// convert the IntPtr value of the filename to a readable string & add to a ListView...
Dim lvi As New ListViewItem(Marshal.PtrToStringAnsi(f_in_cab.NameInCabinet))
/// the FILETIME should be 2 Int32s, but to get the resulting long value required i made it one Int64 [b][Broken External Image][/b]:[URL]http://www.computerhelp.forum/x_images/images/smilies/smile.gif[/URL]
Dim ft As FILETIME
DosDateTimeToFileTime(f_in_cab.DosDate, f_in_cab.DosTime, ft)
Dim d As Date = Date.FromFileTime(ft.dwLowDateTime)
lvi.SubItems.Add(New ListViewItem.ListViewSubItem(lvi, d.ToLongDateString & " " & d.ToLongTimeString))
frm.ListView1.Items.Add(lvi)
FILEFOUND = FILEOP_SKIP
End Select
/// must Return FILEFOUND to continue enumerating the files in the cab.
Return FILEFOUND
End Function
End Class
Code:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim OD As New OpenFileDialog
With OD
.Filter = "CAB files|*.CAB"
.RestoreDirectory = True
End With
If OD.ShowDialog = DialogResult.OK Then
ListView1.Columns(0).Text = OD.FileName
Dim cabinet As New CAB(OD.FileName)
End If
End Sub
Attachments
Last edited by a moderator: