UNLHA32.DLLをVBSから利用してファイルをLZH圧縮する。

お仕事スクリプトで、VBScriptのみによるLZH圧縮という
要望が出てきたので調査、対応してみた。
PCにはMS OfficeとLHUT32というアーカイバが入っている前提。

VBVBAだと割かし実装例が出て来るのだけど、
やはりというか、Declareステートメントの無いVBS環境で
わざわざ動かそうってチャレンジャーは見当たらなかった。
解凍だけならVista以降OS標準で行けるんだが。

利用するDLLはUNLHA32.DLLで用いるのはUnlhaという関数。

UNLHA32.DLL

int WINAPI Unlha(const HWND _hwnd, LPCSTR _szCmdLine,
        LPSTR _szOutput, const DWORD _dwSize)

この関数を、他サイトで見たVBAの実装例を参考に、
作成したラッパー関数が以下。

'Unlha関数(UNLHA32.DLL)を実行する。
'操作に成功したらTrueを、そうでなければFalseを返す
Function ExecUnlha(szCmdLine)
    Const DW_SIZE = 256 '出力バッファサイズ
    Dim command
    
    'UNLHA32.DLL 呼び出しコマンドを生成する
    command = "CALL(""unlha32"", ""Unlha"", ""JJCFJ"", 0, " & """" & szCmdLine & """" & ", 0, " & DW_SIZE & ")"
    
    'unlha32 を呼び出す
    If CreateObject("Excel.Application").ExecuteExcel4Macro(command) = 0 Then
        ExecUnlha = True
    Else
        ExecUnlha = False
    End If
End Function

VBSからのDLL呼び出しにはExcel CALL関数を利用。
他にSFC miniやDynacallを使ったDLL利用例も見たが
追加インストール無しって条件だと、
これ以外で選択の余地は無かった。

Sub Test()
    If ExecUnlha("a c:\work\test.lzh c:\work\test.txt") = False Then
        MsgBox "ExecUnlha error!"
    End If
End Sub

ちょっと悩んだのは引数タイプのところ。
第3引数で使われるバッファ用バイト配列の指定方法だが、
結論としては"JJCFJ"とすることで、実行時エラー無くLZH圧縮を行うことが出来た。

どうやらCALL関数にて参照先の変更を伴う変数を指定する場合、
データ型をFまたはGと指定し、CALL文上では0とすることで、
予め用意されている256バイト領域が割り当てられるようだった。

解り辛い…!というのがこの引数タイプの感想。
そもそもVBS縛りってのが茨の道な気がしないでもないが。

敢てExecuteExcel4Macroで頑張ってみたいなら
下記リンク先を読めば理解が深まるかも知れない。


CALL 関数と REGISTER 関数の使い方 - Office サポート
https://support.office.com/ja-jp/article/CALL-%E9%96%A2%E6%95%B0%E3%81%A8-REGISTER-%E9%96%A2%E6%95%B0%E3%81%AE%E4%BD%BF%E3%81%84%E6%96%B9-06fa83c1-2869-4a89-b665-7e63d188307f

VBScriptAPI 呼び出し ( ソフトウェア ) - 特になし - Yahoo!ブログ
https://blogs.yahoo.co.jp/nobuyuki_tsukasa/5364628.html

VBScript内でdll(参照渡しの引数含む)を利用したいと考えています... - Yahoo!知恵袋
https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1387232963