ZIPファイルの情報を7-zip32.DLLで取得する。


ZIP形式の圧縮ファイルを操作するのは、UnZip32.DLLがデファクトスタンダードとなっていますが、最近発表された7-zip32.DLLでも操作できます。UnZip32.DLLは、解凍(デコード)のみの操作で、圧縮(エンコード)に関してはZip32.DLLのラッパであるZip32J.DLLを使用しなければならないが、7-zip32.DLLであれば、圧縮・解凍のどちらも可能です。

7-zip32.DLLは、「 統合アーカイバラブラリー 」の共通APIの仕様に則っているので、 UnZip32.DLLでの取得方法 とほとんど変わらない方法で取得できます。

書庫ファイルの情報を取り出すには、SevenZipOpenArchive, SevenZipCloseArchive, SevenZipFindFirst, SevenZipFindNextを使用する。

Option Explicit

Private Const FNAME_MAX32 = 512
Private Const FNAME_MAX32PLUS1 = FNAME_MAX32 + 1

' INDIVIDUALINFO構造体
Private Type tagINDIVIDUALINFO
    dwOriginalSize      As Long         ' /* ファイルのサイズ */
    dwCompressedSize    As Long         ' /* 圧縮後のサイズ */
    dwCRC               As Long         ' /* 格納ファイルのチェックサム */
    uFlag               As Long         ' /* 処理結果 */
    uOSType             As Long         ' /* 書庫作成に使われたOS */
    wRatio              As Integer      ' /* 圧縮率 */
    wDate               As Integer      ' /* 格納ファイルの日付(DOS 形式) */
    wTime               As Integer      ' /* 格納ファイルの時刻(〃) */
    szFilename          As String * FNAME_MAX32PLUS1 ' /* 書庫名 */
    dummy1              As String * 3
    szAttribute         As String * 8   ' /* 格納ファイルの属性 書庫固有  */
    szMode              As String * 8   ' /* 格納ファイルの格納モード 〃  */
End Type

' ハンドルと書庫ファイルを結び付けます。
Private Declare Function SevenZipOpenArchive Lib "7-zip32.DLL" _
                                (ByVal hwnd As Long, _
                                 ByVal szFilename As String, _
                                 ByVal dwMode As Long) As Long
' SevenZipOpenArchive() で割り付けたハンドルを解放する。
Private Declare Function SevenZipCloseArchive Lib "7-zip32.DLL" _
                                (ByVal harc As Long) As Long
' 最初の格納ファイルの情報を得ます。
Private Declare Function SevenZipFindFirst Lib "7-zip32.DLL" _
                                (ByVal harc As Long, _
                                 ByVal szWildName As String, _
                                 lpSubInfo As tagINDIVIDUALINFO) As Long
' 2番目以降の格納ファイルの情報を得ます。
Private Declare Function SevenZipFindNext Lib "7-zip32.DLL" _
                                (ByVal harc As Long, _
                                 lpSubInfo As tagINDIVIDUALINFO) As Long
' DOS形式の日付時間をFILETIMEに変換します。
Private Declare Function DosDateTimeToFileTime Lib "kernel32" _
                                (ByVal wFatDate As Long, _
                                 ByVal wFatTime As Long, _
                                 lpFileTime As Currency) As Long

' ローカル時刻は1601年1月1日以降のナノ秒で表される。
' Currencyではミリ秒で表される。
' 1日のミリ秒数で割り、1601年以降の日数を取得する。
' 1601年から1899年までの日数を引き、VBの日数を計算する。
'
' 10,000,000ナノ秒×60秒×60分×24時間÷10,000 = 86,4000,000
' (10,000はCurrencyで固定小数点を調整する)
'
' VBの日付とWin32の日付の違い
' (#1899-12-30# - #1601-01-01#)
Private Const conDayZeroBios As Double = 109205#
Private Const conMillisecondPerDay As Double = 10000000# * 60# * 60# * 24# / 10000#
'
' 実際の使用にあたっては、書庫ファイルのデータは、
' 配列かコレクションに格納したりして使います。
'
Private Sub Command1_Click()
    ' 変数の宣言
    Dim udtINDIVIDUALINFO   As tagINDIVIDUALINFO
    Dim udtFILETIME         As Currency ' 構造体なんだけど通貨型で宣言
    Dim strFileName         As String   ' 書庫ファイル名
    Dim lngArcHandle        As Long     ' 書庫ファイルのハンドル
    Dim lngResult           As Long     ' APIの戻り値用
    Dim strArcFileName      As String   ' 格納ファイル名
    Dim lngArcFileOriginalSize As Long  ' 格納ファイルのサイズ
    Dim lngArcFileCompressedSize As Long ' 格納ファイルの圧縮後のサイズ
    Dim sglArcFileRatio     As Single   ' 圧縮率
    Dim dteArcFileDate      As Date     ' 格納ファイルの日時
    Dim strArcFileAttr      As String   ' 格納ファイルの属性
    Dim strArcFileType      As String   ' 格納ファイルの格納モード
    Dim lngArcFileCRC       As Long     ' 格納ファイルのチェックサム

    ' 書庫ファイル名を格納。
    strFileName = "C:\Documents and Settings\Administrator\My Documents\HEROPA\VBDeFM\vbdfm040-src-20030315.zip"
    ' 書庫ファイルとハンドルを関連付ける。
    lngArcHandle = SevenZipOpenArchive(Me.hwnd, strFileName, 0)
    If lngArcHandle <> 0 Then
        ' 最初の書庫内のファイルの情報を取り出す。
        If SevenZipFindFirst(lngArcHandle, "*", udtINDIVIDUALINFO) = 0 Then    ' *.*では、拡張子の無いファイルがヒットしません。
            Do
                ' ファイル名
                strArcFileName = Left$(udtINDIVIDUALINFO.szFilename, InStr(udtINDIVIDUALINFO.szFilename, vbNullChar) - 1)
                ' ファイルのサイズ
                lngArcFileOriginalSize = udtINDIVIDUALINFO.dwOriginalSize
                ' 圧縮後のサイズ
                lngArcFileCompressedSize = udtINDIVIDUALINFO.dwCompressedSize
                ' 圧縮率
                sglArcFileRatio = udtINDIVIDUALINFO.wRatio / 10
                ' 格納ファイルの日付を取得する。
                ' DOS形式の時間をFILETIMEに変換する。
                lngResult = DosDateTimeToFileTime(CLng(udtINDIVIDUALINFO.wDate), CLng(udtINDIVIDUALINFO.wTime), udtFILETIME)
                ' FILETIMEをVBのDate型に変換する。
                dteArcFileDate = CDate((udtFILETIME / conMillisecondPerDay) - conDayZeroBios)
                ' 属性
                strArcFileAttr = Left$(udtINDIVIDUALINFO.szAttribute, InStr(udtINDIVIDUALINFO.szAttribute, vbNullChar) - 1)
                ' 格納ファイルの格納モード
                strArcFileType = Left$(udtINDIVIDUALINFO.szMode, InStr(udtINDIVIDUALINFO.szMode, vbNullChar) - 1)
                ' 格納ファイルのチェックサム
                lngArcFileCRC = udtINDIVIDUALINFO.dwCRC
                ' 結果をデバッグウィンドウに表示。
                Debug.Print strArcFileName, _
                            lngArcFileOriginalSize, _
                            lngArcFileCompressedSize, _
                            Format$(sglArcFileRatio, "0.0") & "%", _
                            Format$(dteArcFileDate, "yyyy/mm/dd hh:nn:ss"), _
                            strArcFileAttr, _
                            strArcFileType, _
                            Right$("000000" & Hex$(lngArcFileCRC), 6)
            ' 次の格納ファイルの情報を取り出す。
            Loop While SevenZipFindNext(lngArcHandle, udtINDIVIDUALINFO) = 0
        End If
        ' 書庫ファイルハンドルを閉じる。
        lngResult = SevenZipCloseArchive(lngArcHandle)
    End If
End Sub

BackHome