Работа с архивами ZIP средствами windows
Пример ниже показывает некоторые функции для работы с ZIP. Функции не объеденяются общим интерфейсом, то есть каждая из них самодостаточна и автономна. Есть возможность создать архив, распаковать, добавить файл в архив и вывести некоторые данные об файле\ах в архиве.
Платформа: Windows XP и выше
Компилятор: тестировалось на версии
1.03
#INCLUDE Once "windows.bi" #INCLUDE Once "win/shldisp.bi" #INCLUDE Once "win/shlwapi.bi" #INCLUDE Once "win/ole2.bi" '****************************************************************************************************************** ' Function: ExtractZip * ' Description: * ' Extract archive * ' Parameters: * ' szPathZip - the path to the ZIP file * ' szPathOutputFolder - the full path where you want to unpack * ' iOption - options,may be: * ' 0 default * ' 4 Do not display a progress dialog box. * ' 8 Give the file being operated on a new name in a move, copy, * ' or rename operation if a file with the target name already exists. * ' 16 Respond with "Yes to All" for any dialog box that is displayed. * ' 64 Preserve undo information, if possible. * ' 128 Perform the operation on files only if a wildcard file name (*.*) is specified. * ' 256 Display a progress dialog box but do not show the file names. * ' 512 Do not confirm the creation of a new directory if the operation requires one to be created. * ' 1024 Do not display a user interface if an error occurs. * ' 2048 Version 4.71. Do not copy the security attributes of the file. * ' 4096 Only operate in the local directory. Don't operate recursively into subdirectories. * ' 9182 Version 5.0. Do not copy connected files as a group. Only copy the specified files. * ' Examples: * ' All extract: * ' ExtractZip("C:\test.zip\*.*","C:\Test") * ' Extract one file: * ' ExtractZip("C:\test.zip\test.txt","C:\Test") * ' * '****************************************************************************************************************** Function ExtractZip(szPathZip As Zstring Ptr , szPathOutputFolder As Zstring Ptr , iOption As Integer = 0) As Integer Dim As Integer nLen Dim As BSTR bstrZip , bstrFol Dim As HRESULT hres Dim As IShellDispatch Ptr pSD Dim As Folder Ptr pOutFolder If PathIsDirectory(szPathOutputFolder) = 0 Then MessageBox(0,"Destination Folder does not exist!","Error",MB_ICONERROR) Return 0 Endif hres = CoCreateInstance(@CLSID_Shell, NULL, CLSCTX_SERVER ,@IID_IShellDispatch, @pSD) If SUCCEEDED(hres) And pSD <> 0 Then Dim As VARIANT vZipDir,vOutDir,vOptions VariantInit(@vZipDir) vZipDir.vt = VT_BSTR nLen = (lstrlen(szPathZip) + 1) * Sizeof(Wstring) bstrZip = SysAllocStringByteLen(NULL,nLen) MultiByteToWideChar(CP_ACP,0,szPathZip,-1,bstrZip,nLen) vZipDir.bstrVal = bstrZip VariantInit(@vOutDir) vOutDir.vt = VT_BSTR nLen = (lstrlen(szPathOutputFolder) + 1) * Sizeof(Wstring) bstrFol = SysAllocStringByteLen(NULL, nLen) MultiByteToWideChar(CP_ACP,0,szPathOutputFolder,-1,bstrFol,nLen) vOutDir.bstrVal = bstrFol If SUCCEEDED(pSD->lpVtbl->Namespace(pSD,vOutDir,@pOutFolder)) And pOutFolder <> 0 Then VariantInit(@vOptions) vOptions.vt=VT_I4 vOptions.lVal = iOption If SUCCEEDED(pOutFolder->lpVtbl->CopyHere(pOutFolder,vZipDir,vOptions)) Then Function = 1 Endif If pOutFolder Then pOutFolder->lpVtbl->Release(pOutFolder) VariantClear(@vOptions) Endif If pSD Then pSD->lpVtbl->Release(pSD) VariantClear(@vZipDir) VariantClear(@vOutDir) Endif End Function '*************************************************** ' Function: CreateEmptyZip * ' Description: * ' Create new empty archive * ' Parameters: * ' szPathZip - the name new ZIP file * ' Examples: * ' CreateEmptyZip("Test.zip") * ' * '*************************************************** Function CreateEmptyZip(szPathZip As Zstring Ptr) As Integer Dim As Handle hFile hFile = CreateFile(szPathZip,GENERIC_WRITE Or GENERIC_READ, FILE_SHARE_READ Or FILE_SHARE_WRITE,0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,0) If hFile = INVALID_HANDLE_VALUE Then Return 0 Else Dim As Byte bArray(...) = {80, 75, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} Dim iBuf As Integer If WriteFile(hFile,Cast(LPCVOID,@bArray(0)),Ubound(bArray)+1,@iBuf,0) Then Function = 1 CloseHandle(hFile) Endif End Function '*************************************************************************************************************** ' Function: CopyFileInZip * ' Description: * ' Copy file in the archive * ' Parameters: * ' szPathZip - the path to the ZIP file * ' szPathFile - the full path to the file for archiving * ' iOption - options,may be: * ' 0 default * ' 4 Do not display a progress dialog box. * ' 8 Give the file being operated on a new name in a move, copy, * ' or rename operation if a file with the target name already exists. * ' 16 Respond with "Yes to All" for any dialog box that is displayed. * ' 64 Preserve undo information, if possible. * ' 128 Perform the operation on files only if a wildcard file name (*.*) is specified. * ' 256 Display a progress dialog box but do not show the file names. * ' 512 Do not confirm the creation of a new directory if the operation requires one to be created. * ' 1024 Do not display a user interface if an error occurs. * ' 2048 Version 4.71. Do not copy the security attributes of the file. * ' 4096 Only operate in the local directory. Don't operate recursively into subdirectories. * ' 9182 Version 5.0. Do not copy connected files as a group. Only copy the specified files. * ' Examples: * ' CopyFileInZip("C:\test.zip","C:\Test.txt") * ' or * ' CopyFileInZip("C:\test.zip\folder\","C:\Test.txt") * ' * '*************************************************************************************************************** Function CopyFileInZip(szPathZip As Zstring Ptr, szPathFile As Zstring Ptr, iOption As Integer = 0) As Integer Dim As Integer nLen Dim As BSTR bstrZip , bstrFol Dim As HRESULT hres Dim As Integer iCount, iTempCount Dim As IShellDispatch Ptr pSD Dim As Folder Ptr pOutFolder Dim As FolderItems Ptr pFolderItems If PathFileExists(szPathFile) = 0 Then MessageBox(0,"File does not exist!","Error",MB_ICONERROR) Return 0 Endif hres = CoCreateInstance(@CLSID_Shell, NULL, CLSCTX_SERVER ,@IID_IShellDispatch, @pSD) If SUCCEEDED(hres) And pSD <> 0 Then Dim As VARIANT vZipDir,vFile,vOptions VariantInit(@vZipDir) vZipDir.vt = VT_BSTR nLen = (lstrlen(szPathZip) + 1) * Sizeof(Wstring) bstrZip = SysAllocStringByteLen(NULL,nLen) MultiByteToWideChar(CP_ACP,0,szPathZip,-1,bstrZip,nLen) vZipDir.bstrVal = bstrZip VariantInit(@vFile) vFile.vt = VT_BSTR nLen = (lstrlen(szPathFile) + 1) * Sizeof(Wstring) bstrFol = SysAllocStringByteLen(NULL, nLen) MultiByteToWideChar(CP_ACP,0,szPathFile,-1,bstrFol,nLen) vFile.bstrVal = bstrFol If SUCCEEDED(pSD->lpVtbl->Namespace(pSD,vZipDir,@pOutFolder)) And pOutFolder <> 0 Then If SUCCEEDED(pOutFolder->lpVtbl->Items(pOutFolder,@pFolderItems)) And pFolderItems <> 0 Then If SUCCEEDED(pFolderItems->lpVtbl->get_Count(pFolderItems,@iCount)) Then iTempCount = iCount Endif Endif VariantInit(@vOptions) vOptions.vt=VT_I4 vOptions.lVal = iOption If SUCCEEDED(pOutFolder->lpVtbl->CopyHere(pOutFolder,vFile,vOptions)) Then Do Until iTempCount + 1 = iCount If SUCCEEDED(pOutFolder->lpVtbl->Items(pOutFolder,@pFolderItems)) And pFolderItems <> 0 Then If SUCCEEDED(pFolderItems->lpVtbl->get_Count(pFolderItems,@iCount)) Then Else Exit Do Endif Else Exit Do Endif Sleep(10) Loop Function = 1 Endif If pOutFolder Then pOutFolder->lpVtbl->Release(pOutFolder) If pFolderItems Then pFolderItems->lpVtbl->Release(pFolderItems) VariantClear(@vOptions) Endif If pSD Then pSD->lpVtbl->Release(pSD) VariantClear(@vZipDir) VariantClear(@vFile) Endif End Function '****************************************************************** ' Function: DisplayNameZip * ' Description: * ' Print the name and size of each file in a single folder * ' Parameters: * ' szPathZip - the path to the ZIP file * ' Examples: * ' DisplayNameZip("C:\test.zip") * ' or * ' DisplayNameZip("C:\test.zip\Folder") * ' * '****************************************************************** Function DisplayNameZip(szPathZip As Zstring Ptr) As Integer Dim As Integer nLen Dim As BSTR bstrZip , bstrName Dim As HRESULT hres Dim As Integer iCount, iInfoSize Dim As IShellDispatch Ptr pSD Dim As Folder Ptr pOutFolder Dim As FolderItems Ptr pFolderItems Dim As FolderItem Ptr pItem hres = CoCreateInstance(@CLSID_Shell, NULL, CLSCTX_SERVER ,@IID_IShellDispatch, @pSD) If SUCCEEDED(hres) And pSD <> 0 Then Dim As VARIANT vZipDir,vOptions VariantInit(@vZipDir) vZipDir.vt = VT_BSTR nLen = (lstrlen(szPathZip) + 1) * Sizeof(Wstring) bstrZip = SysAllocStringByteLen(NULL,nLen) MultiByteToWideChar(CP_ACP,0,szPathZip,-1,bstrZip,nLen) vZipDir.bstrVal = bstrZip If SUCCEEDED(pSD->lpVtbl->Namespace(pSD,vZipDir,@pOutFolder)) And pOutFolder <> 0 Then If SUCCEEDED(pOutFolder->lpVtbl->Items(pOutFolder,@pFolderItems)) And pFolderItems <> 0 Then If SUCCEEDED(pFolderItems->lpVtbl->get_Count(pFolderItems,@iCount)) Then If iCount > 0 Then For i As Integer = 0 To iCount-1 VariantInit(@vOptions) vOptions.vt=VT_I4 vOptions.lVal = i If SUCCEEDED(pFolderItems->lpVtbl->Item(pFolderItems,vOptions,@pItem)) And pItem <> 0 Then If SUCCEEDED(pItem->lpVtbl->get_Name(pItem,@bstrName)) And _ _ SUCCEEDED(pItem->lpVtbl->get_Size(pItem,@iInfoSize)) And _ _ bstrName <> 0 Then Print *bstrName , iInfoSize ' Print the name and size of each file Function = 1 Endif Endif Next Endif Endif Endif If pOutFolder Then pOutFolder->lpVtbl->Release(pOutFolder) If pFolderItems Then pFolderItems->lpVtbl->Release(pFolderItems) If pItem Then pItem->lpVtbl->Release(pItem) Endif If pSD Then pSD->lpVtbl->Release(pSD) VariantClear(@vZipDir) Endif End Function '*************************************************************************************** ' TEST * ' 1) Create empty ZIP archive * ' 1) Create file TXT * ' 3) Copy file TXT in the archive * ' 4) Display name and size file in the archive * ' 5) Create new folder "ExtractZipFile" * ' 6) Extract ZIP in the folder "ExtractZipFile" * ' * '*************************************************************************************** OleInitialize(NULL) If CreateEmptyZip("Test.zip") Then If CreateEmptyZip("test.txt") Then If CopyFileInZip("Test.zip","test.txt") Then DisplayNameZip("Test.zip") If CreateDirectory(Strptr("ExtractZipFile"),0) Then If ExtractZip("Test.zip\*.*",Exepath & "\ExtractZipFile") = 0 Then MessageBox(0,"Error extract!","Error",MB_ICONERROR) Endif Else MessageBox(0,"Error create folder!","Error",MB_ICONERROR) Endif Else MessageBox(0,"Error copy file in the archive!","Error",MB_ICONERROR) Endif Else MessageBox(0,"Error creating TXT file!","Error",MB_ICONERROR) Endif Else MessageBox(0,"Error creating archive!","Error",MB_ICONERROR) Endif Print "Press any key!" Sleep OleUninitialize()