Pythonでctypesを使ってUNLHA32.dllを扱う
PythonでLhaを扱いたかったのだけど、ググッてもモジュールもなければ、ブログのエントリーもないので調査しました。
どうやらctypesを使うといいらしい。
ctypesも初めて使うのでいろいろ迷いましたが、割と簡単に使うことができるようです。
以下ソース
#! coding=sjis
from ctypes import windll, wintypes, Structure, c_char, byref
TEST_ARC = r'c:\temp\hogearchive1.lzh'
# INDIVIDUALINFO型の構造体を扱うためにStructureを継承したクラスを作る。_fields ではなく _fields_ なので注意
class INDIVIDUALINFO(Structure):
_fields_ = [
('dwOriginalSize', wintypes.DWORD),
('dwCompressedSize', wintypes.DWORD),
('dwCRC', wintypes.DWORD),
('uFlag', wintypes.UINT),
('uOSType', wintypes.UINT),
('wRatio', wintypes.WORD),
('wDate', wintypes.WORD),
('wType', wintypes.WORD),
('szFileName', c_char * 513), #配列は * を使う
('dummy1', c_char * 3),
('szAttribute', c_char * 8),
('szMode', c_char * 8)
]
individualinfo = INDIVIDUALINFO()
#UNLHA.dllを扱うにはwindll.LoadLibraryを使う
openlha = windll.LoadLibrary('UNLHA32.dll')
#UnlhaOpenArchiveの引数を渡して、指定の書庫ファイルに対応したハンドルを受け取る
# 引数
# _hwnd UNLHA32.DLL を呼び出すアプリのウィンドウのハンドル。
# _szFileName 書庫ファイル名。
# _dwMode UnlhaFindFirst() 等の処理のモード。
#
hdl = openlha.UnlhaOpenArchive(None, TEST_ARC, None)
if hdl:
#OpenArchive系の関数はハンドルとINDIVIDUALINFO型の構造体のポインタを引数にとることが多いので最初に作ったINDIVIDUALINFOクラスのインスタンスをbyref関数でくるんで渡す。
if openlha.UnlhaFindFirst(hdl, '*.*', byref(individualinfo)) == 0:
while True:
print individualinfo.szFileName
if openlha.UnlhaFindNext(hdl, byref(individualinfo)) != 0:
break
#close
openlha.UnlhaCloseArchive(hdl)
ちなみにINDIVIDUALINFO型の構造体は以下のようなもの
typedef struct {
DWORD dwOriginalSize; /* ファイルのサイズ */
DWORD dwCompressedSize; /* 圧縮後のサイズ */
DWORD dwCRC; /* 格納ファイルのチェックサム */
UINT uFlag; /* 処理結果 */
/* Status flag */
UINT uOSType; /* 書庫作成に使われた OS */
WORD wRatio; /* 圧縮率 */
WORD wDate; /* 格納ファイルの日付(DOS 形式) */
WORD wTime; /* 格納ファイルの時刻(〃) */
char szFileName[FNAME_MAX32 + 1]; /* 格納ファイル名 */
char dummy1[3];
char szAttribute[8]; /* 格納ファイルの属性(書庫固有) */
char szMode[8]; /* 格納ファイルの格納モード(〃) */
} NDIVIDUALINFOA, *LPINDIVIDUALINFOA;
実行結果は以下の通り
C:\temp>python unlha.py
/temp/hoge1/
/temp/hoge1/difflib.py
/temp/hoge1/difflib.pyc
/temp/hoge1/dircache.py
/temp/hoge1/dis.py
/temp/hoge1/dis.pyc
/temp/hoge1/doctest.py
/temp/hoge1/doctest.pyc
/temp/hoge1/DocXMLRPCServer.py
他の関数も同じようにして使うことが出来そうです。
ctypesはなかなかいいのではないでしょうか?
Pythonはzipを簡単に使えるので自分だけで使う分にはLhaは扱う必要ないです。
perm link: /blog/entry/ctypesunlha/



