2016年10月13日木曜日

ファイルやフォルダをCAB形式で圧縮するスクリプト

先ほどの記事でCAB形式は使わないことにする、と記載しましたが、その結論に至る問題が発覚したのはこの記事で公開するプログラムを作成した後だったのです。
問題はexpandコマンドだけではないですが、それがクリアになったら、もしかしたら心変わりするかもしれませんし、正常に動作するケースもありますので、一応作ったものを公開します。




expandコマンドが
正常に動作することを確認したケース → 複数のファイルやフォルダをまとめて圧縮した場合。
正常に動作しないことを確認したケース → 単一のファイルを圧縮した場合。

ちなみにmakecabで/Fオプションを使っても使わなくてもexpandコマンドは上記のようになりました。

以下、ソース
<job>
<script>
arg = WScript.Arguments
if(!arg.length){
WScript.Echo('ファイルかフォルダをドラッグ&ドロップして起動してください')
WScript.Quit()
}
main = function(){
// 全ての関数などのローディングが終了してからこの関数が実行される。
// この関数の終了=スクリプトの終了。
圧縮()
WScript.Echo('終了')
WScript.Quit()
}
get構成情報=function(path){
// pathの中身はフォルダPath限定。ファイルのPathや無効なPathではないことは呼び出し元で確認済み。
// サブフォルダやファイルなどの名前や階層を示すテキストデータを返す。
var arrKey=[fs.GetFileName(path)], str構成情報 = '.Set DestinationDir="'+arrKey.join('\\')+'"\r\n'
var funファイル=function(p){ for0L(getFileList(p), function(i,name){ str構成情報 += '"'+p+'\\'+name+'"\r\n' }) }
var funフォルダ=function(p){
for0L(getDirList(p), function(i,name){
arrKey.push(name)
str構成情報 = '.Set DestinationDir="'+arrKey.join('\\')+'"\r\n'
funファイル(p+'/'+name)
funフォルダ(p+'/'+name)
arrKey.pop()
})
}
funファイル(path)
funフォルダ(path)
return str構成情報
}
sortArguments=function(){
// このWSFファイルにドロップされたアイテムをファイルとフォルダに分けて整理する。
var arrファイル=[], arrフォルダ=[], path, swD, swF
for(var i=0,L=arg.length;i<L;i++){
path = arg(i)
swD = fs.FolderExists(path)
swF = fs.FileExists (path)
if(swD && swF){
// win7でこのケースが発生しうるか試しにやってみたけど「同名のファイルが存在します」という警告が表示されて、作れないようになっていた。
// しかし念のため残しておく。
WScript.Echo('Pathが同一のファイルとフォルダが存在しています。\n'+path+'\n\n上記理由により対象アイテムを判別できないため、処理を中断します。')
WScript.Quit()
}else if(!swD && !swF){
// コマンドラインからキー入力でpathを入力する時にタイプミスなどにより存在しないpathになってしまっている場合
WScript.Echo('指定されたPathに対応するファイル(フォルダ)が見つかりません。\n'+path+'\n\n上記理由により、処理を中断します。')
WScript.Quit()
}
(swD ? arrフォルダ : arrファイル).push(path)
}
return {フォルダ:arrフォルダ, ファイル:arrファイル}
}
圧縮=function(){
var obj=sortArguments(), arrファイル=obj.ファイル
var str構成情報 = arrファイル.length ? ('"'+arrファイル.join('"\r\n"')+'"\r\n') : ''
for0L(obj.フォルダ, function(i,path){ str構成情報 += get構成情報(path) })
var pathBAT=gsf2+'/makecab_'+(new Date()).getTime()+'.bat', path構成=pathBAT+'.構成'
Write(path構成, str構成情報)
Write(pathBAT, [
'cd '+fun(fs.GetParentFolderName(arrファイル.length ? arrファイル[0] : obj.フォルダ[0])),
'makecab '+Dパラメータ+' /F '+fun(path構成),
'del setup.inf',
'del setup.rpt'
].join('\r\n'))
shell.Run(fun(pathBAT), 0, true)
fs.DeleteFile(pathBAT)
fs.DeleteFile(path構成)
}
// makecabの/Dスイッチで各種設定ができる。
// MaxDiskSizeを指定しないとcabファイルは1.38MB区切りで複数個作成される。
// MaxDiskSizeは512の倍数で指定する。
Dパラメータ = '/D MaxDiskSize='+(512*2*1000*1000*1000)
// 以下、基礎関数
AXO = function(name){return new ActiveXObject(name)}
fs = AXO('Scripting.FileSystemObject')
shell = AXO('WScript.Shell')
gsf2 = fs.GetSpecialFolder(2)
Read = function(p){var o=fs.OpenTextFile(p), s=o.AtEndOfStream?'':o.ReadAll(); o.Close(); return s}
Write = function(path,v){with(fs.CreateTextFile(path)){Write(v);Close()}}
RAS = function(p){return Read(p).split('\r\n')}
for0L=function(arr,fun){for(var i=0,L=arr.length,res;i<L;i++){if(res=fun(i,arr[i])){return res}}}
forIn=function(obj,fun){var name,res; for(name in obj){if(res=fun(name, obj[name])){return res}}}
fun = function(path){return path.indexOf(' ')<0 ? path : ('"'+path+'"')}
WshNetwork = AXO("WScript.Network")
getDirList = function(path, swFile){
var pathTMP=gsf2+'/getDirList_'+(new Date()).getTime()+'.txt', arr
shell.Run('cmd /C dir /A'+(swFile?'-':'')+'D /B "'+path+'" > "'+pathTMP+'"' , 0 , true)
arr = fs.FileExists(pathTMP) ? RAS(pathTMP) : []
arr.pop()
try{fs.DeleteFile(pathTMP)}catch(e){}
return arr
}
getFileList=function(path){return getDirList(path, true)}
// メイン処理実行
main()
</script>
</job>
view raw make cab.wsf hosted with ❤ by GitHub

0 件のコメント:

コメントを投稿