2015年10月5日月曜日

Windowsで、OS標準機能のzip圧縮/解凍を使用する(WSH編)

こんにちは。近藤です。


以前の記事では、Windows10から標準搭載されたPowerShell v5のコマンド例を記載していましたが、記事のアクセス数から考えると、おそらく「Windows10以外で使用するコマンドが知りたい」というかたが多かったと思います。
そこで、Windows Script Host(以降、WSHと記載します)やPowerShell v4での例は「ネットで探すとすぐに見つかるので、割愛します」としていましたが、せっかく多くのかたに来ていただいているので、このBlogにもPowerShell V5以外の方法を記載しておきます。

今回は、
  • WSHでzipファイルの操作を作成し、バッチで呼び出し
を記載します。

WSHは、現在ではその座をPowerShellに譲った一世代前のスクリプト実行環境ですが、WSHはWindows OSの標準機能なので、現在MicrosoftがサポートしているすべてのWindows OSで実行することができます。

解凍
WSHでzipファイルの解凍を行うには、PowerShell v5のように簡単に扱うことはできず、スクリプトを書く必要があります。

解凍スクリプト例(UnZip.vbs):
Option Explicit
dim objShell, objWshShell, objFolder, ZipFile, i

if WScript.Arguments.Count < 1 or WScript.Arguments.Count > 2 then
    WScript.Echo "Usage: CScript.exe UnZip.VBS ZIPFile [objFolder]"
    WScript.Quit
end if

Set objShell = CreateObject("shell.application")
Set objWshShell = WScript.CreateObject("WScript.Shell")
Set ZipFile = objShell.NameSpace (WScript.Arguments(0)).items
if WScript.Arguments.Count = 2 then
    Set objFolder = objShell.NameSpace (WScript.Arguments(1))          '指定された解凍先フォルダ
else
    Set objFolder = objShell.NameSpace (objWshShell.CurrentDirectory)  '省略時はカレントディレクトリへ
end if

objFolder.CopyHere ZipFile, &H14            '進行状況ダイアログボックス非表示 + ダイアログボックスは [すべてはい]

実行時には、上記のスクリプト内にもあるとおり、先頭に”Cscript.exe”と付けます。
C:\> CScript.exe UnZip.VBS c:\source\source.zip c:\temp

圧縮
WSHでzipファイルの圧縮を行うときも、スクリプトを書く必要があります。
圧縮時のスクリプトは、解凍時のスクリプトに比べて複雑です。

圧縮スクリプト例(CompZip.VBS):
Option Explicit
dim objFSO, objFile, objShell, InputFile, ZipFile, hdrary, strbuf, ZipItemCount, i

if WScript.Arguments.Count < 2 then
    WScript.Echo "Usage: CScript.exe CompZip.VBS ZIPFile InputFiles..."
    WScript.Quit
end if

ZipFile=WScript.Arguments.Item(0)

' Zipファイル新規作成
hdrary = Array(80, 75, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)  'zipファイルのヘッダ情報
For i = 0 To UBound(hdrary)
  strbuf = strbuf & Chr(hdrary(i))
Next

' ファイル新規作成(既存ファイルは上書きされる)
Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.CreateTextFile(ZipFile, True)
objFile.Write(strbuf)
objFile.Close
Set objFile = Nothing
Set objFSO = Nothing

' 新規作成したZipファイルに、圧縮元ファイルを追加
Set objShell = CreateObject("Shell.Application")
Set objFile = objShell.NameSpace(ZipFile)
ZipItemCount = objFile.Items().Count
for i = 1 to WScript.Arguments.Count - 1
    InputFile = WScript.Arguments.Item(i)
    objFile.CopyHere(InputFile)

    ' 追加完了待ち
    Do While ZipItemCount = objFile.Items().count
        WScript.Sleep(250)
    Loop
    ZipItemCount = ZipItemCount + 1
next
Set objFile = Nothing
Set objShell = Nothing

実行時は、以下のようなコマンドです。
C:\> CScript.exe CompZip.vbs c:\temp\target.zip c:\temp\file1.txt c:\temp\file2.txt c:\temp\file3.txt

このような感じで、Windows OS標準のコマンドを使用してzipファイルを扱えるようになります。

補足
なお、前回の記事でも記載したとおり、
  • zipファイルのパスワードは、解凍時のみ指定可能で、圧縮には暗号化の引数自体がありません。
  • 解凍時のパスワード指定を引数で与えることができず、パスワードで暗号化されたzipファイルが来た場合は、パスワードを入力するダイアログボックスが表示されます。
また、zipファイルを作成したアーカイバによっては、Windows OSの標準機能では解凍できないファイルになっている場合があります。

補足2
圧縮スクリプト例のみですが、環境によっては圧縮元ファイルが全て登録されていない状態で終了してしまったり(スクリプト中では、「Zipファイルに全て登録された」というステータス(が、実際は登録が完了していない))、スクリプトが途中でループしてしまったり(スクリプト中では、「Zipファイルにまだ登録されていない」というステータス(が、実際は登録されている))することを確認しています。

1 件のコメント:

  1. エクスプローラーから、ユーザー操作以外の方法で ZIP ファイルを扱うことは想定されていません。
    CopyHere メソッドを使用して ZIP ファイルからファイルを取り出したり、ZIP ファイルにファイルを格納したりすることもサポート対象外となります。

    https://support.microsoft.com/ja-jp/help/2679832

    返信削除