今は遥かに効率の良い圧縮形態が出ているけども、まだまだ現役なzip圧縮。
元からあるdllを参照に追加するだけかと思いきや、.Net Frameworkバージョンが古い場合は色々制限があって想定と違った話。
最初にやった事
今回は共有フォルダに置かれているエクセルを、ZIPで固めて添付してメールを送るシステムを作る事に。
ZIPするならZipFileクラスで行うのが一般的らしいのでまず以下を実施してみた。
プロジェクト→参照の追加で【C:\Windows\Microsoft.NET\Framework\v4.0.30319】にある、
System.IO.Compression.FileSystem.dll、System.IO.Compression.ZipFile.dllを追加する。
※最後のv4.0.30319は人によりけり

実行環境
OS:Win10 1903
IDE:Visual Studio Express 2013
MakeZip(System.IO.Compression)
フォルダパスを指定してZipするので、圧縮したいファイルと同じ階層に同じ名前のフォルダを作成し、その中にファイルをコピーさせてみた。すっごい回りくどいけどテスト段階だったからご愛敬と言う事で・・・
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
using System.IO.Compression; private void MakeZip() { // 圧縮する様のフォルダパス string strFilePath = @"\\192.168.100.100\共有フォルダ\テスト\"; // ディレクトリが存在しない場合 if (Directory.Exists(strPathName) == false) { // ディレクトリを作成する Directory.CreateDirectory(strPathName); } // ファイルコピー File.Copy(@"\\192.168.100.100\共有フォルダ\TEST.xlsx", @"\\192.168.100.100\共有フォルダ\テスト\TEST.xlsx"); // Zip化パス string strZip = @"\\192.168.100.100\共有フォルダ\テスト.zip"; // ディレクトリが存在しない場合 if (Directory.Exists(strZip) == false) { // Zip生成 ZipFile.CreateFromDirectory(strPath, strZip); } } |
これで圧縮は出来た、が、TEST.xlsxならOKだけどもテスト.xlsxだと文字化けして失敗してしまった(デフォルトがUTF-8)。
その回避策としてCreateFromDirectoryに対し下記の様にZip生成時にパラメータを追加してエンコードを行った訳です↓
1 2 |
// Zip生成 ZipFile.CreateFromDirectory(strPath, strZip, CompressionLevel.Optimal, true, Encoding.GetEncoding("sjis")); |
ここで問題が・・・
ここからが本題。結論から言うと CompressionLevel.Optimal ← これが.Net Frameworkバージョン4.5からでないとダメらしく、アセンブリ参照が不足していますと起こられてしまう。
※4.5以上の人は上記コードコピッペで動作します。

その他もろもろにも影響を及ぼすから~とかなんとかでバージョンを上げるって解が無い残念な弊社。かと言ってファイル名に日本語不可運用もちょっと非現実的・・・
じゃあどうするか??
DotNetZipを使用する
DotNetZipは.NET Framework 2.0以上で使用出来る強い味方。使用方法もとてもシンプルで使いやすく、古いFramework縛りならこれが最適解。ただし、本家のサイトはココなのだけれども、どこにも必要なファイルが無い(2020/10/26現在)
ここからdll直でダウンロードしてきて、プロジェクト→参照の追加で追加してさえあげれば、
以下の様な記述で文字化けせずにZip処理が出来た↓
MakeZip(DotNetZip)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
using Ionic.Zip; using Ionic.Zlib; private void MakeZip() { // 圧縮するファイルパス string strFilePass = @"\\192.168.100.100\共有フォルダ\テスト.xlsx"; // 圧縮処理 ZipFile zip = new ZipFile(Encoding.GetEncoding("shift_jis")); zip.Password = "password"; zip.AddFile(strFilePass, ""); // ファイルの拡張子をzipに変える strFilePass = strFilePass.Replace(Path.GetExtension(strFilePass),"") + ".zip"; zip.Save(strFilePass); } |
AddFileは第二引数に書庫内のパスを指定できるのですが、省略するとそれまでの階層が全部出来てしまう仕様。
192.168.100.100フォルダ→共有フォルダ→テスト.xlsxてな具合。
なので今回の様に単一ファイルをzipで送りたい場合等は空白指定をした方がよいですね。
後同じファイルをAddFileするとエラーになるので、重複する恐れのある実装の場合File.Exists等でチェックしましょう。
コメント