kiyo_hikoのブログ

メモ+日記?

zip由来のエラー「マルチボリューム セットの最後のディスクを挿入してください」対策(おまけでzip数が多いときの原因特定方法)

Windows10使っていて、タイトルにあるエラーが頻発してとても鬱陶しかったので対策しました。

どんなエラー?

Windows起動中に画像のようなダイアログが頻繁に出現するようになります。
特に何も操作してない時でもバンバン出ます。
邪魔すぎます。

f:id:kiyo_hiko:20190930000739p:plain
マルチボリューム セットの最後のディスクを挿入してください

原因とか症状は?

ぶっ壊れたzipファイルが「どこか」に居るとこの症状が出るっぽいです。
例えば「ダウンロード」フォルダーに壊れたzipが居ると、別に「ダウンロード」開いてないのにさっきのダイアログがバンバンダイアログが出ます。
Windowsのシステムサービスが裏で検索インデックスらへんを作ってるせいかな?

修復方法

壊れたzipがどこかにあるはずです。それを特定します。
見つけたらzipを消すか(要らなければ)、WinRARとかで修復を試みます(大事なファイルなら。修復できなければ諦めて消す)

以上。

おまけ:zipがたくさんあって、特定が大変な場合でも壊れたzipを検出する

拙者のケースがこれなのですが、掲示板のログとか収集してて数千個とかzipがあります。
壊れたzipとか手動で探せる気がしません。

なので、PowerShellで壊れたzipを探しました。
PowerShellの起動/操作手順とコードを掲示します。ある程度知っている人を想定して、基本的な操作は省きます。

手順1. PowerShellを起動する

最近のWindows10では、「Winキー+x」→「i」でPowerShellが起動します。または他の方法で起動します。

手順2. コードを編集する

次のようなコードをエディターで書きます。

Add-Type -AssemblyName system.io.compression.filesystem

$workdir = "C:\Users\" # ここを探したいフォルダーのパスに変えましょう
$zips = gci $workdir -Recurse -Filter "*.zip"

foreach ($zip in $zips) {
    Write-Host $zip.FullName
    $files = [io.compression.zipfile]::OpenRead($zip.FullName).Entries
}

意味は以下:

  • Add-Type:zip操作用ライブラリを読み込む(多分)
  • $workdir:探したいパスを変数に代入
  • $zips = 以下:gciコマンドでファイルをリスト化、その時に子フォルダーも検索して「*.zip」でフィルターする
  • foreach:$zipsにフィルターしたファイル一覧が入ってるのでループするよと言いたい
  • Write-Host:画面にファイル名を書き出す
  • $files:zip内のファイルを一覧で取得する

$filesに一覧を拾っておこうとすると壊れたzipから検出できない→ここでエラーが出ます。

手順3. コードをPowerShellに貼り付けて実行

コード全部コピーします。 その後、PowerShellのウィンドウをクリック→「Alt+Space」メニューから→「編集」→「貼り付け」するか、右クリックで貼り付けます。 - すぐ実行されない場合、PowerShellウィンドウにした状態でEnterキーを2回ぐらい叩きましょう。

壊れたzipを無事見つけると、以下のような表示になります。

C:\Users\kiyohiiko\Downloads\BoardsLog20190925.zip
"1" 個の引数を指定して "OpenRead" を呼び出し中に例外が発生しました: "中央ディレクトリの終わりレコードが見つかりません。"
+     $files = [io.compression.zipfile]::OpenRead($zip.FullName).Entrie ...
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : InvalidDataException

Write-Hostで画面にファイル名を書き出しているので、エラーの直前の行に書かれているzip名(上の例ではBoardsLog20190925.zip)が壊れたzipだとわかります。 このノリで1件または複数件のzipが炙り出されるので、それぞれに消すなり修復して対策すればOKです。

もっと高速かつ楽な方法があれば少し知りたい

以上です。