海外とやり取りする ZIP の文字化けに疲れて、7-Zip をフォークした
この記事で紹介するのは 7-Zip の非公式フォークです。Igor Pavlov 氏および公式 7-Zip プロジェクトとは関係ありません。
発端
中国の取引先から届いた ZIP を日本語版 Windows で開くと、中身がこうなっていました。
1-1.ト・ → ~スィ」イトミミヤ」ゥ・ム・ソゲ・・
一つ二つなら手で直しますが、毎週届きます。しかも自分は受け取るだけでなく、日本のお客さまに ZIP を送る側でもあるので、逆向きの化けも起こします。
原因は ZIP の古い仕様です。ZIP のファイル名フィールドには「どの文字コードで書いたか」という情報がありません。general purpose bit 11(UTF-8 フラグ)が立っていれば UTF-8 と判断できますが、多くのツールは、ファイル名がローカルコードページで表現できてしまう場合はフラグを立てず、ローカルのバイト列をそのまま書き込みます。
中国語版 Windows で圧縮すればファイル名は GBK(CP936)のバイト列でフラグなし。それを日本語版Windows で開けば、受け取った側は CP932 と解釈するしかありません。作った側も開いた側も規格通りに動いていて、それでも化ける。悪いのは仕様です。
公式 7-Zip の GUI には、これを直す入口がありません(CLI に無文書の -mcp= があるだけです)。毎回別のツールに切り替えるのも面倒になってきたので、フォークして自分で付けることにしました。
作ったもの
- リポジトリ: https://github.com/r404r/7zip
- ベース: 公式 7-Zip 26.03(Windows x64)
- ライセンス: 公式と同じ LGPL 2.1 以降(+ unRAR 制限)。ソースは全部公開しています
化けた ZIP を開くとき
解凍ダイアログに Name code page のドロップダウンを足しました。化けている ZIP に対して 936 (Chinese Simplified) を選べば、そのまま正しい名前で解凍されます。
既定は Auto、つまり従来どおりの動作です。そして選んだ値は記憶しません。毎回 Auto に戻ります。これは手抜きではなく意図的で、コードページの指定は「目の前のこの一つのアーカイブへの応急処置」だからです。覚えさせてしまうと、次に開いた別のコードページのアーカイブが今度は化けます。
.7z や .gz には影響しません。内部では zip.cp=936 のようにフォーマットを限定したプロパティとして ZIP ハンドラだけに渡しています。無条件に配ると、cp を知らないハンドラがアーカイブを開けなくなるためです。
どのコードページか分からないとき
そもそも相手が何で作ったのか分からないことのほうが多いので、7zFM(ファイルマネージャ)側にも入口を付けました。View → Name Code Page... です。
アーカイブを開いたまま、コードページを変えて開き直せます。閲覧中のフォルダ位置も維持されるので、一覧を見ながら「これでもない、これだ」と試せます。
対象は、実ファイル 1 個で構成された普通の ZIP と非圧縮 tar だけです。.tar.gz のようにハンドラを重ねるもの、親アーカイブのメモリ上から直接開いたもの、ファイルマネージャがパスを切り詰めたものではメニューが灰色になります。開き直しは同期処理なので、大きなアーカイブではその間 7zFM が止まります(進捗もキャンセルもまだありません)。開き直しに失敗した場合は、アーカイブを閉じて親フォルダに戻り、エラーを出します。
送る側で化けさせない
圧縮ダイアログには Use UTF-8 for file names を追加しました。ZIP のときだけ出て、既定で ON です。
ファイル名を UTF-8 で書き、bit 11 を立てます。つまりアーカイブ自身に「これは UTF-8 です」と書かせるわけで、規格に従うツールなら相手がどの言語環境でも化けません。Parameters 欄に cu / cl / cp を手で書いた場合は、そちらが優先されます。
相手が古い国産の解凍ツール(bit 11 を見ないもの)だと分かっている場合は、Parameters にcl=on を指定すると CP932 のまま書けます。このとき 0x7075 拡張フィールドに UTF-8 名も併記されるので、モダンなツールから見ても正しく読めます。
コマンドラインから
7zz.exe l "-mzip.cp=936" archive.zip -sccUTF-8
zip. のプレフィックスがフォークの追加分で、プロパティを ZIP ハンドラだけに送ります。PowerShell ではクォートが要ります(-mzip.cp=936 が . の位置で分割されてしまうため)。 -sccUTF-8 はコンソール出力の文字コード指定で、これは公式の機能です。UTF-8 のターミナルではこれを付けないと、せっかく正しく解読した名前が表示の段階で化けます。ここで一度はまりました。
公式 7-Zip と並べて入れられます
MSI は独自の ProductCode とインストール先(7-Zip-fork)を持っていて、公式 7-Zip を上書きしません。右クリックメニューも「7-Zip-fork」という別名・別 CLSID で登録するので、公式の「7-Zip」メニューと並びます。インストールしたくなければ portable 版もあります。
UI は日本語で動きます。公式の言語ファイル 90 数言語をそのまま同梱していて、初回起動時にシステムの言語が選ばれます(Options → Language で変更できます)。フォークが追加した項目も日本語・簡体字・繁体字に訳してあります。細かい話ですが、公式のソースツリーには言語ファイルが入っておらず、バイナリ配布物にしか含まれていません。だからソースからビルドしただけでは英語のままになります。同梱しているのはそのためです。
ダウンロード
最新版: 26.03-fork.1 (Releases 一覧)
MSI、portable の zip、SHA256SUMS を置いてあります。バージョンは 26.03-fork.N で、公式 26.03 をベースにしたフォーク側の第 N リリースという意味です。
中身の話を少しだけ
最初は本家にプルリクエストを送るつもりでした。ただ、公式 GitHub リポジトリでは執筆時点でマージされた PR が確認できず(メンテナは issue 側で活動しています)、フォークとして各リリースに追随する方針にしました。
公式の新版はマージで取り込みます(rebase しません)。リリースタグが履歴に残りますし、コンフリクトは公式 1 リリースにつき 1 回解けば済みます。変更は「1 テーマ 1 ブランチ」で、先に落ちるテストを書いてから実装し、別のレビューを通してから統合しています。CI は全ターゲットのビルドに加えて、エンコーディングの動作テストと、MSI のレジストリ登録内容の検証まで走ります。
LGPL 対応として、改変したファイルには全部に変更告知の行を入れ(CI で強制しています)、パッケージには LGPL 全文(copying.txt)を同梱しています。
できないこと・気をつけること
Windows x64 のみです。ヘルプファイル(.chm)は同梱していないので Help ボタンは効きません。右クリックメニューは Windows 11 の新しいメニューには出ず、「その他のオプションを確認」の中に入ります。32bit アプリのダイアログにも出ません。
公式のアップデートには手作業で追随しています。最新の公式機能がすぐ入るわけではありません。
個人がメンテしているフォークです。at your own risk でお願いします。何かあれば Issues へどうぞ。
同じ問題で消耗している方の役に立てば幸いです。届いた ZIP が化けていたら解凍ダイアログでコードページを選ぶ、送るときは既定のまま UTF-8 フラグ付きで送る。それだけで大半は片が付きます。



