HOME
  Security
   Software
    Hardware
  
FPGA
  CPU
   Android
    Raspberry Pi
  
nLite
  Xcode
   etc.
    ALL
  
English Translate 中文翻訳
LINK
BACK
 

2018/02/01

C#で ZIPファイル解凍ツール UnZipをソースリスト 1行で自作する方法、Windows .NET専用 C#で ZIPファイル解凍ツール UnZipをソースリスト 1行で自作する方法、Windows .NET専用

(Visual Studio 2013の C# .NET 4.5で ZipFile.ExtractToDirectoryを使い、UnZip解凍ツールを作成)

Tags: [Windows], [無人インストール]





● ZIPファイル解凍ツールをソースリスト 1行で作る方法

 Visual Studio 2013の C#で ZipFile.ExtractToDirectoryを使います。
ZipFile.ExtractToDirectory("ZIPファイルのパス", "解凍先ディレクトリ");
 以上!

 ZipFile クラス > ZipFile メソッド > ExtractToDirectory メソッド
ZipFile.ExtractToDirectory メソッド (String, String)
 指定した zip アーカイブのすべてのファイルをファイル システムのディレクトリに抽出します。
 名前空間: System.IO.Compression
 .NET Framework: 4.5以降で使用可能
 ※ Visual Studio 2012以降が必要


● Visual Studio 2013の練習で作成した ZIPファイル解凍専用アプリ

 Visual Studio 2013の練習で作成した ZIPファイル解凍専用アプリ。

UnZip.cs
using System.IO.Compression;

namespace UnZip
{
    class Program
    {
        static void Main(string[] args)
        {
            if (args.Length < 2) return;

            string zipPath = args[0];
            string extractPath = args[1];

            ZipFile.ExtractToDirectory(zipPath, extractPath);
        }
    }
}
 ※ 解凍時に既にファイルが存在していると例外でアプリが落ちます。


●上書き対応の場合は ZipArchiveEntry.ExtractToFileを使用します。

ZipFileExtensions.ExtractToFile メソッド (ZipArchiveEntry, String, Boolean)

public static void ExtractToFile(
	this ZipArchiveEntry source,
	string destinationFileName,
	bool overwrite
)

パラメーター
source Type: System.IO.Compression.ZipArchiveEntry
ファイルを抽出する zip アーカイブ エントリ。

destinationFileName Type: System.String
エントリの内容から作成するファイルのパス。 相対パスと絶対パスのどちらかを指定することができます。 相対パスは、現在の作業ディレクトリに対して相対的に解釈されます。

overwrite Type: System.Boolean
宛先ファイルと同じ名前の既存のファイルを上書きする場合は true。それ以外の場合は false。

using System.IO;
using System.IO.Compression;

namespace UnZip
{
    class Program
    {
        static void Main(string[] args)
        {
            if (args.Length < 2) return;

            string zipPath = args[0];
            string extractPath = args[1];
            bool overwrite = true;

            using (ZipArchive archive = ZipFile.OpenRead(zipPath))
            {
                foreach (ZipArchiveEntry entry in archive.Entries)
                {
                    // 完全なファイル名/ ディレクトリ名
                    String combineFilePath = Path.Combine(extractPath, entry.FullName);

                    // ディレクトリを作成する
                    if (entry.Name == "") {
                        CreateDirectory(combineFilePath);
                        continue;
                    }

                    // ディレクトリの有無を調べる
                    DirectoryInfo di = Directory.GetParent(combineFilePath);
                    if (!di.Exists)
                    {
                        CreateDirectory(di.FullName);
                    }

                    // ファイルを解凍する
                    entry.ExtractToFile(combineFilePath, overwrite);
                }
            }
        }

        static DirectoryInfo CreateDirectory(string path)
        {
            if (Directory.Exists(path))
            {
                return null;
            }

            return Directory.CreateDirectory(path);
        }
    }
}


●ついでに HTTPのファイルにも対応してみた版

 ZIPファイル名を指定した場合は ZIPファイルを解凍、
 http://~
 https://~
 ftp://~
 を指定した場合はインターネットから ZIPファイルをダウンロードしつつ解凍します。

 // Solution Explorer - Add Reference - Assemblies - Framework
 // System.IO.Compression
 // System.IO.Compression.FileSystem
 // .NET Framework 4.5以降で使用可能


using System;
using System.IO;
using System.IO.Compression;
using System.Net;

namespace UnZip
{
    class Program
    {
        static void Main(string[] args)
        {
            if (args.Length < 2) return;

            string zipPath = args[0];
            string extractPath = args[1];
            bool overwrite = true;

            try
            {
                // 文字列の先頭を調べて Webかファイルかを切り替える
                if ( (zipPath.StartsWith("http") || zipPath.StartsWith("ftp"))
                    && zipPath.Contains("://") )
                {
                    DoWebRequest(zipPath, extractPath, overwrite);
                }
                else
                {
                    DoFileRequest(zipPath, extractPath, overwrite);
                }
            }
            catch (Exception e)
            {
                // 例外は全部キャッチして内容を表示する
                Console.WriteLine("Exception: " + e);
            }
        }


        // Webのファイルを ZIP解凍
        private static void DoWebRequest(string zipUrlPath, string extractPath, bool overwrite)
        {
            // Create a request for the URL.
            WebRequest request = WebRequest.Create(zipUrlPath);

            // Get the response.
            using (WebResponse response = request.GetResponse())
            {
                // Display the information.
                Console.WriteLine("ContentLength: " + response.ContentLength);
 //                Console.WriteLine("Headers: " + response.Headers);

                // Get the stream containing content returned by the server.
                using (Stream dataStream = response.GetResponseStream())
                {
                    using (ZipArchive archive = new ZipArchive(dataStream, ZipArchiveMode.Read))
                    {
                        ExtractZipArchive(archive, extractPath, overwrite);
                    }
                }
            }
        }


        // ファイルを ZIP解凍
        private static void DoFileRequest(string zipFilePath, string extractPath, bool overwrite)
        {
            FileInfo fi = new FileInfo(zipFilePath);
            // ファイルサイズを取得
            long fileSize = fi.Length;
            Console.WriteLine("FileSize: " + fileSize);

            using (ZipArchive archive = ZipFile.OpenRead(zipFilePath))
            {
                ExtractZipArchive(archive, extractPath, overwrite);
            }
        }


        // ZIP解凍の共通処理
        private static void ExtractZipArchive(ZipArchive archive, string extractPath, bool overwrite)
        {

#if false
            // ExtractToDirectory関数は上書き発生時に例外する
            archive.ExtractToDirectory(extractPath);

#else
            // ExtractToFile関数はファイル単位で処理をする
            long fileCount = 0L;
            foreach (ZipArchiveEntry entry in archive.Entries)
            {
                String fullName = entry.FullName;

                // NFD UTF-8-MAC対策
                if (!fullName.IsNormalized())
                {
                    fullName = fullName.Normalize();
                }

                // Mac避け "__MACOSX/"
                if (fullName.StartsWith("__MACOSX/"))
                {
                    continue;
                }
                // Mac避け ".DS_Store"
                if (fullName.EndsWith(".DS_Store"))
                {
                    continue;
                }


                // 完全なファイル名/ ディレクトリ名
                String combineFilePath = Path.Combine(extractPath, fullName);

                // ディレクトリを作成する
                if (entry.Name == "")
                {
                    CreateDirectory(combineFilePath);
                    continue;
                }

                // ディレクトリの有無を調べる
                DirectoryInfo di = Directory.GetParent(combineFilePath);
                if (!di.Exists)
                {
                    CreateDirectory(di.FullName);
                }

                // ファイルを解凍する
                entry.ExtractToFile(combineFilePath, overwrite);
                ++fileCount;
            }

            Console.WriteLine("Extracted: " + fileCount);
#endif
        }


        // ディレクトリの有無を調べて作成する
        private static DirectoryInfo CreateDirectory(string path)
        {
            if (Directory.Exists(path))
            {
                return null;
            }

            return Directory.CreateDirectory(path);
        }
    }
}

※ ZIPファイルのディレクトリ名やファイル名の決まり(entry.FullName)で、
・ディレクトリの場合は最後に必ず "/"が付く
・ディレクトリ名やファイル名の先頭に "/"は付かない
 となっています。(ZIPアプリを作る場合に例外ケースの実装が不要になります)


●エラー 1 型または名前空間名 'ZipArchive' が見つかりませんでした。using ディレクティブまたはアセンブリ参照が不足しています。

 「参照設定」で「参照の追加(R)...」で Compressで検索(絞込み)
System.IO.Compression
System.IO.Compression.FileSystem
 を追加する。

 .NET Framework: 4.5以降で使用可能
 ※ Visual Studio 2012以降が必要


● C#で NFDを NFCに変換する方法、MacOSの濁点や半濁点の文字が文字化けするのを対策

 MacOSで作成した ZIPファイルを Windowsで解凍する時にファイル名の濁点や半濁点の文字が文字化けするのを Unicodeの正規化形式で対策する。

NFC Normalization Form Canonical Composition、正規化形式C
NFD Normalization Form Canonical Decomposition、正規化形式D

 Windowsでは NFCの「正規化形式C」、ガギグゲゴ
 ガ=U+30AC

 macOS OS Xでは NFDの「正規化形式D」、カ゛キ゛ク゛ケ゛コ゛
 カ゛=U+30AB、U+3099

● C#で macOS OS Xの UTF-8-MAC NFD形式を Windowsの UTF-8 NFC形式に変換する方法
var converted = "カ゚キ゚ク゚ケ゚コ゚".Normalize();

● C#で UTF-8の文字列が NFCかどうかを判定する方法
var isNfc = "ガギグゲゴ".IsNormalized(); // true ガ
var isNfc = "カ゚キ゚ク゚ケ゚コ゚".IsNormalized(); // false カ゛

U+795E 神 ネ申
U+FA19 神 示申

WEB国語教室 > 日本の文字とUnicode 第5回 続・漢字とUnicode (安岡孝一)


● macOS Mac OS Xで作成した Zipファイルを Windowsで解凍する時の Mac避け

 NFD形式のファイル名を NFC形式に変換し、"__MACOSX"ディレクトリや ".DS_Store"ファイルを解凍しない様に無視します。
  foreach (ZipArchiveEntry entry in archive.Entries)
  {
    String fullName = entry.FullName;

    // NFD UTF-8-MAC対策
    if (!fullName.IsNormalized())
    {
        fullName = fullName.Normalize(); // NFD形式を NFC形式に変換
    }

    // Mac避け "__MACOSX/"
    if (fullName.StartsWith("__MACOSX/"))
    {
        continue;
    }
    // Mac避け ".DS_Store"
    if (fullName.EndsWith(".DS_Store"))
    {
        continue;
    }

    // 解凍処理を行なう
    ...

  }


● Visual Studio C#の未使用 usingの削除

 「編集(E)」>「IntelliSense(I)」>「usingの整理(O)」>「未使用の usingの削除(R)」

 ※ Javaで言う所の未使用の importの削除。




Tags: [Windows], [無人インストール]

●関連するコンテンツ(この記事を読んだ人は、次の記事も読んでいます)

Microsoft Visual C++ ランタイムライブラリ 再頒布可能パッケージのまとめ 2018年版 2005~2017まで
Microsoft Visual C++ ランタイムライブラリ 再頒布可能パッケージのまとめ 2018年版 2005~2017まで

  Microsoft Visual C++ 2005、2008、2010、2012、2013、2015、2017の各バージョンの最新版 Runtime librariesのまとめ

Visual Studio 2019 Professionalを無人インストールする方法、完全自動でインストール
Visual Studio 2019 Professionalを無人インストールする方法、完全自動でインストール

  VS2019を完全オフラインインストール&コンポーネント選択の事前設定で自動インストールする

Visual Studio 2017 Professionalを無人インストールする方法、完全自動でインストール
Visual Studio 2017 Professionalを無人インストールする方法、完全自動でインストール

  VS2017を完全オフラインインストール&コンポーネント選択の事前設定で自動インストールする

Visual Studio 2015 Professionalを無人インストールする方法、完全自動でインストール
Visual Studio 2015 Professionalを無人インストールする方法、完全自動でインストール

  VS2015を Update 3適用済みとコンポーネント選択の事前設定でインストール時の手間を省く

Visual Studio 2013 Professionalを無人インストールする方法、完全自動でインストール
Visual Studio 2013 Professionalを無人インストールする方法、完全自動でインストール

  VS2013を Update 5適用済みとコンポーネント選択の事前設定でインストール時の手間を省く

Visual Studio 98を無人インストール(自動インストール)する方法
Visual Studio 98を無人インストール(自動インストール)する方法

  インストールするコンポーネントも事前に設定する事で同一環境の構築が楽にできます

Visual Studio 2013に Windows 10 SDK + UwpDesktopで UWPの機能を素の Windowsアプリから使用
Visual Studio 2013に Windows 10 SDK + UwpDesktopで UWPの機能を素の Windowsアプリから使用

  VS2013に Win 10 SDKをインストールして Uwp Desktopで UWPの機能を従来の Windowsアプリで動かす

Visual Studio 2013の C#で 日本語対応の OCR文字認識アプリを自作する方法
Visual Studio 2013の C#で 日本語対応の OCR文字認識アプリを自作する方法

  オフライン環境で動作可能な 世界各国語対応の OCR文字認識アプリを作成、MS製 OCRライブラリを使用

Visual Studio 2013の C#で日本語対応の手書き文字認識アプリを自作する方法
Visual Studio 2013の C#で日本語対応の手書き文字認識アプリを自作する方法

  オフライン環境で動作する世界各国語対応の手書き文字認識アプリを作成、MS製 手書き認識ライブラリを使用

Open XML SDKを使用して Officeのファイルを C#で自在に操る方法
Open XML SDKを使用して Officeのファイルを C#で自在に操る方法

  Microsoft Officeのファイルをプログラムで生成したり直接中身の読み取りができます

Visual Studio Communityのまとめ Professional と同等機能が無償
Visual Studio Communityのまとめ Professional と同等機能が無償

  Visual Studio Communityの 2013 Update 5、2015 Update 3、2017 version 15.6のまとめ

Visual Studioの各バージョンと開発できる .NET Frameworkの各バージョンのまとめ
Visual Studioの各バージョンと開発できる .NET Frameworkの各バージョンのまとめ

  .Microsoft.NET Framework Developer Packの各バージョンのダウンロードまとめ。言語パック等

Windows 10対応 Microsoft Speech使用の音声認識アプリ
Windows 10対応 Microsoft Speech使用の音声認識アプリ

  SpeechRecognizeApp 音声認識エンジンを使用してマイク入力の音声を認識します

Windows 10の音声合成エンジンを使用して入力した文字列を喋る & Waveファイル書き出し
Windows 10の音声合成エンジンを使用して入力した文字列を喋る & Waveファイル書き出し

  SpeechApp Windows 10用 Speech 音声合成 Text-to-Speech TTSのアプリ

Visual Studioの C#や MFC C++用のサンプルアプリのリンク集
Visual Studioの C#や MFC C++用のサンプルアプリのリンク集

  Visual Studioの C#や MFC C++でアプリを作る時の参考資料として

Windowsの Input Method Manager IMEや TSF Text Services Frameworkの公式情報源のまとめ
Windowsの Input Method Manager IMEや TSF Text Services Frameworkの公式情報源のまとめ

  Windowsで IME Input Method Manager関連のアプリを作成する時の情報 ImeTrayもこの辺を必死に読んだ

Microsoft Office 2016を無人インストール(自動インストール)する方法
Microsoft Office 2016を無人インストール(自動インストール)する方法

  インストールするコンポーネントを事前に設定する事で同一環境の構築が楽にできます MSオフィス 2016

Windows 10を全自動で最後まで手間要らずでインストールする方法
Windows 10を全自動で最後まで手間要らずでインストールする方法

  autounattend.xmlの応答ファイルを使用して Windows 10を無人インストールする。大量展開時に便利

Adobe Acrobat Reader関係のまとめ 2018年版、自動インストール、無人インストール方法
Adobe Acrobat Reader関係のまとめ 2018年版、自動インストール、無人インストール方法

  アップデート手順など、Adobe Reader XI、X、Acrobat Reader 9、Acrobat Reader 8



[HOME] | [BACK]
リンクフリー(連絡不要、ただしトップページ以外は Web構成の変更で移動する場合があります)
Copyright (c) 2018 FREE WING,Y.Sakamoto
Powered by 猫屋敷工房 & HTML Generator

http://www.neko.ne.jp/~freewing/software/visual_c_sharp_unzip_tool/