環境
Windows10 (7も多分いけるはず)
コンパイル
事前にcscにパスを通しておく。
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe
compile.bat
csc /r:C:\Windows\Microsoft.NET\Framework64\v4.0.30319\System.IO.Compression.FileSystem.dll ^
/r:C:\Windows\Microsoft.NET\Framework64\v4.0.30319\System.IO.Compression.dll %*
下記でコンパイルできる。
compile.bat ソース名.cs
ソースコード
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.IO;
using System.Text;
using System.Windows.Forms;
using System.IO.Compression; // to use zip
class ZipTest : Form
{
ZipTest()
{
var btn = new Button(){
Size = new Size(200,25),
Text = "Save zip file",
};
btn.Click += (s,e)=>{
string destPath = Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), "ZipTest_Output.zip");
CreateZipFile(destPath);
};
Controls.Add(btn);
}
void CreateZipFile(string destZipPath)
{
try {
// ZipFile.Open で Zipを作成するとき、すでにファイルが存在していると例外が発生する。
// 上書きしたい場合は、すでにファイルが存在する場合は削除しておく。
// if (File.Exists(destZipPath)) {
// File.Delete(destZipPath);
// }
using( ZipArchive archive = ZipFile.Open(destZipPath, ZipArchiveMode.Create) ) {
ZipArchiveEntry entry;
entry = archive.CreateEntry("Test1.txt", CompressionLevel.Optimal);
using (StreamWriter writer = new StreamWriter(entry.Open()))
{
writer.WriteLine("FileContentSample-1");
}
entry = archive.CreateEntry(@"hoge\Test2.txt", CompressionLevel.Optimal);
using (StreamWriter writer = new StreamWriter(entry.Open()))
{
writer.WriteLine("FileContentSample-2");
}
// 既存のファイル(第一引数)を読み込んでzip内にファイルをつくる場合
// archive.CreateEntryFromFile( @"C:\Test.txt", "a.txt", CompressionLevel.Optimal );
}
}
catch(IOException e) {
MessageBox.Show(e.ToString());
}
catch(UnauthorizedAccessException e) {
MessageBox.Show(e.ToString());
}
}
[STAThread]
static void Main(string[] args)
{
Application.Run(new ZipTest());
}
}
フォルダからzipを作成する場合は
※zipにフォルダを追加するには、archive.CreateEntryFromFile で頑張るしかなさそう。
もう少し実用的なサンプル
指定された 1個のフォルダ または 複数のファイル(フォルダを含んではいけない)をzip化する。
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.IO;
using System.Text;
using System.Windows.Forms;
using System.IO.Compression; // to use zip
class ZipMaker : Form
{
static bool PreCheck(string[] args, out bool dirMode, out string errMsg)
{
errMsg = null;
if (args.Length==1 && Directory.Exists(args[0]))
{
dirMode = true;
return true;
}
else
{
dirMode = false;
foreach (string arg in args)
{
if (!File.Exists(arg))
{
if (Directory.Exists(arg))
{
errMsg = "This tool does not support multiple entries including folder. Only supports 1 folder, or files";
}
else
{
errMsg = "File not found: \"" + arg + "\"";
}
return false;
}
}
}
return true;
}
static void CreateZipFromFiles(string destZipPath, string[] files)
{
// https://stackoverflow.com/questions/15133626/creating-directories-in-a-ziparchive-c-sharp-net-4-5
// https://docs.microsoft.com/ja-jp/dotnet/api/system.io.compression.ziparchive?view=netcore-3.1
try
{
if (File.Exists(destZipPath))
{
// すでにファイルが存在する場合は削除する。
File.Delete(destZipPath);
}
using( ZipArchive archive = ZipFile.Open(destZipPath, ZipArchiveMode.Create) )
{
foreach(string s in files)
{
string path = Path.GetFullPath(s);
if (File.Exists(path))
{
archive.CreateEntryFromFile( path, Path.GetFileName(path), CompressionLevel.Optimal );
}
else
{
if (Directory.Exists(path))
{
Console.WriteLine("This tool does not support multiple entries including folder. Only supports 1 folder, or files");
Console.WriteLine("Ignored:\"" + path + "\"");
}
else
{
Console.WriteLine("File not found.");
Console.WriteLine("Ignored:\"" + path + "\"");
}
}
}
}
}
catch(IOException e)
{
MessageBox.Show(e.ToString());
}
catch(UnauthorizedAccessException e)
{
MessageBox.Show(e.ToString());
}
}
static string DestPathFromFileSaveAs(string defaultZipPath, string defaultZipName)
{
SaveFileDialog dlg = new SaveFileDialog();
dlg.FileName = defaultZipName;
dlg.InitialDirectory = defaultZipPath;
dlg.Filter = "ZIP file(*.zip)|*.zip";
dlg.FilterIndex = 1;
dlg.Title = "Select file name to save";
dlg.RestoreDirectory = true;
dlg.OverwritePrompt = true;
//dlg.CheckPathExists = true;
if ( dlg.ShowDialog() == DialogResult.OK )
{
return dlg.FileName;
}
return null;
}
[STAThread]
static void Main(string[] args)
{
bool dirMode;
string errMsg;
if (args.Length==0){return;}
string path0 = Path.GetFullPath(args[0]);
string parent0 = Path.GetDirectoryName(path0);
if ( !PreCheck(args, out dirMode, out errMsg))
{
MessageBox.Show(errMsg);
}
string destPath;
if (dirMode)
{
destPath = DestPathFromFileSaveAs(parent0, Path.GetFileName(path0) + ".zip");
if(destPath!=null)
{
ZipFile.CreateFromDirectory(path0, destPath);// src folder, dest zip
}
}
else
{
if (args.Length >= 2)
{
destPath = DestPathFromFileSaveAs(parent0, Path.GetFileName(parent0) + ".zip");
}
else
{
destPath = DestPathFromFileSaveAs(parent0, Path.GetFileName(path0) + ".zip");
}
if(destPath!=null)
{
CreateZipFromFiles(destPath, args);
}
}
}
}