2016年5月25日水曜日

[WSH]ZIPファイルを作成して、その中にファイルやフォルダを入れる[JScript]

ZIPファイルを作成して、その中にファイルやフォルダをコピーするプログラムのサンプル。
MS系のScriptingの神とも呼ばれる吉岡 照雄さんの作品を参考にさせていただきました。
なぜそのまま利用させてもらわないのかと言えば、私はVBScriptが苦手で、出来るだけJScriptを利用したいからです。。

最初にZIPファイルを作成してますが、何故コレでZIPファイルが出来るのか意味不明です。。

「アイテム数」はコピー完了確認用ループに入る前に毎回取得してますが、「for(i=0」のところでアイテム数=0にして、そのあとはインクリメントで完了確認ループ中のみ取得するようにした方が高速になるのでは?とか、

何かのトラブルでコピー完了確認のループが終わらない場合はフリーズしちゃう…とか、プログラムを見直して気になる点はありますが、今までコレを利用していて速度が気になったりフリーズしたりということが無かったので、そのままにしときます。


※右記のOSでのみ動作確認済み:Win7、XP
<job>
<script>
arg = WScript.Arguments, L=arg.length
if(!L){WScript.Echo('引数を指定してください'); WScript.Quit()}
fs = new ActiveXObject('Scripting.FileSystemObject')
shell = new ActiveXObject('Shell.Application')
Write = function(path,v){try{with(fs.CreateTextFile(path)){Write(v);Close()}}catch(e){WScript.Echo('Write Err.\n'+path)}}
getNS = function(p){return shell.NameSpace(p)} // NameSpace = shellオブジェクトで扱う「Folder Object」を取得するメソッド
getPFN = function(p){return fs.GetParentFolderName(p)}
// ZIPファイル作成
path0 = arg(0)
pathZIP = getPFN(path0).replace(/([^\\\/])$/,'$1/')+fs.GetBaseName(path0)+'.zip'
if(fs.FileExists(pathZIP)){
WScript.Echo('下記PathにZIPファイルを作成しようとしましたが、同じPathのファイルが既に存在しているため、処理を中断します。\n\n'+pathZIP)
WScript.Quit()
}
Write(pathZIP,'PK'+String.fromCharCode.apply(null,'56000000000000000000'.split(''))) // ← ZIPファイルのヘッダー
// ZIPファイルのFolderObjectを取得する
zip = getNS(pathZIP)
// ZIPファイルの中にファイル(フォルダ)をコピー
for(i=0;i<L;i++){
file = getNS(getPFN(arg(i))).ParseName(fs.GetFileName(arg(i)))
// ParseName = shellオブジェクトで扱う「Folder Item Object」を取得するメソッド。
// fs.GetFileで取得できるものとは別物っぽい。
// GetFileで取得したものをCopyHereに渡してもエラーにはならないが、ZIPファイルには何も入らなかった。
// zipファイルにアイテムを追加する前のアイテム数を取得しておく。
アイテム数 = zip.Items().Count + 1
zip.CopyHere(file)
// ZIPファイル内のアイテム数が増えるまで待機してから次に進まないと、取りこぼしが生じる。(3つのファイルを入れたつもりが2つしか入ってないとか)
while(zip.Items().Count<アイテム数){WScript.Sleep(1)}
}
</script>
</job>
view raw zip.wsf hosted with ❤ by GitHub

0 件のコメント:

コメントを投稿