[VBS][7zip]コマンドラインからドライブを圧縮するとき特定のフォルダを圧縮から除外する

# 設定
圧縮対象となるドライブ　Eドライブ
圧縮ファイル名 E.zip
圧縮ファイルの保存先 c:\user\nama\Documents
7zipはprogram files(x86)ではなくC:\Programfiles\7-zip\にあるとする。

#7zipのコマンドラインでドライブを圧縮するときの問題
System Volume Informationフォルダ
Recycle.Bin フォルダ
を圧縮して、これをEドライブに解凍するとRecycle.Binが壊れるらしく、ごみ箱が壊れました。と表示される
このため、コマンドラインで圧縮する場合、これを除外した方が安全なようだ。
しかしながら、これをやろうとするととても困難だ。

## スクリプトの中核部分

Set objDocFol = fs.getfolder("C:\users\name\Documents")
strScr = """" & WSH.ExpandEnvironmentStrings("%PROGRAMW6432%") & "\7-zip\7z.exe """ & " a -tzip -y -r """ & objDocFol.Path & "\E.zip""" & " " & """E:\""" & " -xr!""E:\$RECYCLE.BIN\"" -xr!""E:\System Volume Information\"" "
WSH.exec strscr

##ポイント

1. 除外するフォルダにワイルドカードは付けない。E:\$RECYCLE.BIN\\* は不可
2. 除外するフォルダのオプション（スィッチ）は-xでrがリカース（サブフォルダまで）という意味らしい。!はワイルドカードという説もあるがはっきりしない。解説では-x[r[-|0]]{@listfile|!wildcard}:exclude filename
3. 念のために-xr!のあとのフォルダ名は二重引用符で囲む
4. 環境変数は通常のProgramFilesである変数を使う。一般的には%PROGRAMFILES%でよいはずだが、なぜかこの意味がProgram Files(x86)になるときがあり、ファイルが見つかりません。というエラーが出る。
5. 複数のフォルダを除外したい場合、-xr!を複数使って除外する。
6. zipファイルに除外するフォルダが含まれていないかチェックする場合、「隠しファイル」にチェックするだけでは表示されない。オプションから表示タブ 詳細設定　保護されたオペレーティングシステムファイルを表示しない（推奨）のチェックボックスを「オフ」にしてフォルダーに適用すること。
7.zipの中身を見るときは6の設定をしたうえで、zipファイルを右クリックしプログラムで開く（H）からエクスプローラーを選択する。7zipを選ぶと大変なことになるので、この操作は誤操作しないこと。

この反対の機能として特定のファイルだけを解凍する方法もある。
[コマンドラインで、zipファイルから特定のファイルのみ解凍する](http://blog.livedoor.jp/ryanorano/archives/58882007.html)

```vbnet:Compress.vbs
Const WindowsFolder = 0
Const SystemFolder = 1
Const TemporaryFolder = 2

Dim fs, ofol, ofile, oSubFol, WSH, i, objDocFol, oShell, strScr, RetVal, tgFolder, tmfolder, dt, acApp, oLogFile, strNewfile, strOldfile
Set fs = CreateObject("Scripting.FIlesystemObject")
Set WSH = CreateObject("WScript.Shell")
Set oShell = CreateObject("Shell.Application")
Set objDocFol = fs.GetFolder("C:\users\name\Documents") 'Change Your Computer Username
Set tgFolder = fs.GetFolder("E:\") 'Compress Drive
Set tmfolder = fs.GetSpecialFolder(TemporaryFolder)
'Make File List result.txt on temproray folder
If fs.FileExists(tmfolder.Path & "\result.txt") Then fs.DeleteFile (tmfolder.Path & "\result.txt")
strCmd = "Cmd.exe /c """ & "Dir " & """""" & "E:\*.*"""" /s /a-d /b >""" & tmfolder.Path & "\result.txt"""
WSH.Run strCmd
'Same Name zip File name change
If fs.FileExists(objDocFol.Path & "\E.zip") Then
dt = fs.GetFile(objDocFol.Path & "\E.zip").DateLastModified
strOldfile = CStr(objDocFol.Path & "\E.zip") 'you must change String Datatype
strNewfile = CStr(objDocFol.Path & "\E" & Replace(Replace(Replace(dt, "/", "", 1, -1), ":", "", 1, -1), " ", "", 1, -1) & ".zip")
fs.MoveFile strOldfile, strNewfile 'Change filename with fso is Movefile method

'fs.GetFile(oDocFol.Path & "\E.zip").Name = strNewfile 'objDocFol.Path & "\E" & Replace(Replace(Replace(dt, "/", "", 1, -1), ":", "", 1, -1), " ", "", 1, -1) & ".zip" 'Such Method occur error

End If

strScr = """" & WSH.ExpandEnvironmentStrings("%PROGRAMW6432%") & "\7-zip\7z.exe """ & " a -tzip -y -r """ & objDocFol.Path & "\E.zip""" & " " & """E:\""" & " -xr!""E:\$RECYCLE.BIN\"" -xr!""E:\System Volume Information\"" "
Debug.Print strScr

WSH.Exec strScr

If Err.Number <> 0 Then MsgBox Err.Number & Err.Description
Set fs = Nothing
Set oShell = Nothing
Set WSH = Nothing
Wscript.Quit
```

##再びEドライブに解凍する場合
念のために確認を促すメッセージ付き とりあえずパスワードなし

```vbnet:Exctract.vbs
Dim fs, ofol, ofile, oSubFol,WSH, i, objDocFol, oShell, strScr, RetVal
Const ppass = ""
If msgbox("Eドライブへ解凍します。System Volume Infomation,$RECYCLE.BINを削除しましたか?", _
vbYesNo,"解凍の確認です")=vbNo then WScript.Quit
Set fs = createobject("Scripting.FIlesystemObject")
Set WSH = createobject("WScript.Shell")
Set oShell = createobject("Shell.Application")
Set objDocFol = fs.getfolder("C:\users\name\Documents")
Set ofile = fs.GetFile(objDocFol.Path & "\E.zip")

strScr = """%ProgramFiles%" & "\7-zip\7z.exe "" x " & oFile.Path & " -y -oE:\" ' -ir!" & oFile.Path & """ ' -ppass " & chr(34) & strZip & chr(34) & " " & chr(34) & strPath & oFile.Name & chr(34)

wsh.exec strscr

if err.number <> 0 then msgbox err.number,err.description

set fs= Nothing

set oShell = Nothing

set WSH = Nothing

Wscript.Quit
```

# 参考
[rename a file using VBScript - StackOverFlow]( https://stackoverflow.com/questions/17660117/rename-a-file-using-vbscript)
[7zip: Exclude hidden directories]（https://stackoverflow.com/questions/29749398/7zip-exclude-hidden-directories）
この説明を日本語に置き換えるのは非常に苦労する。
おそらくワイルドカードは末尾ではなく途中ならきくらしい。
しかし名前の途中は効かないときがある。
例えば
*\.svn\
\*\output\
は有効だが
\*\out\*\はエラーになった。
たとえばE:\$\*\はエラーになった。
-xr!"E:\$\*\"
は成功する。なのでフォルダ名がわかっているときはワイルドカードに頼らない方がよい。

# ごみ箱が壊れた場合にレジストリとかいじらないで対応する応急処置
 
1. Eドライブを空にする
2. デスクトップのごみ箱を右クリックしてごみ箱を空にする。
3. 再起動する
4. デスクトップのごみ箱を右クリックしてプロパティ。
5. Eドライブを選択し、選択した場所の設定で、ごみ箱にファイルを移動しないで、削除と同時にファイルを消去するを選択
6. 削除の確認メッセージを表示するのチェックをオフ。