Leaders dynamic_sysop Posted August 30, 2005 Leaders Posted August 30, 2005 (edited) Hi folks, long time since i done this http://www.xtremedotnettalk.com/x_images/images/smilies/frown.gif 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 ... '/// 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 it's 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 msdn's 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 '/// we've found a file in the CAB [img=http://www.xtremedotnettalk.com/x_images/images/smilies/smile.gif] FILEINCABINET = PSP_FILEFOUND_CALLBACK(Context, Notification, Param1, Param2) '/// here we can also extract the files from the CAB. '/// but we'll 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 Int32's, but to get the resulting long value required i made it one Int64 [img=http://www.xtremedotnettalk.com/x_images/images/smilies/smile.gif] 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 the way to use it, from a Form ... 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 i've included a zipped example source code http://www.xtremedotnettalk.com/x_images/images/smilies/smile.gifCABFiles_in_NET.zip Edited July 25, 2006 by PlausiblyDamp Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.