// Input Processing Operations
 protected override void ProcessRecord()
 {
     this.WriteObject(SessionLocation.GetUnresolvedPath(this.SessionState, this.Path));
 }
示例#2
0
        // ----------------------------------------------------------------------------------------------------
        // Pre-Processing Operations
        // ----------------------------------------------------------------------------------------------------
        // (None)


        // ----------------------------------------------------------------------------------------------------
        // Input Processing Operations
        // ----------------------------------------------------------------------------------------------------
        protected override void ProcessRecord()
        {
            foreach (var src_zipfilepath in SessionLocation.GetResolvedPath(this.SessionState, this.Path))
            {
                // Validation (Source File Existence Check):
                if (!File.Exists(src_zipfilepath))
                {
                    throw new FileNotFoundException();
                }

                // SET Destination Directory Path
                var dest_dirpath = this.DestinationPath is null?
                                   Directory.CreateDirectory(SessionLocation.GetUnresolvedPath(this.SessionState, System.IO.Path.GetFileNameWithoutExtension(src_zipfilepath))).FullName:
                                   SessionLocation.GetUnresolvedPath(this.SessionState, this.DestinationPath);

                // Validation (Destination Directory Existence Check):
                if (!Directory.Exists(dest_dirpath))
                {
                    throw new DirectoryNotFoundException();
                }

                // Should Process
                if (this.ShouldProcess($"Source: '{src_zipfilepath}', Destination:'{dest_dirpath}'", "ファイルの展開"))
                {
                    // using ZipFile
                    using (ZipFile zip = ZipFile.Read(src_zipfilepath, new ReadOptions()
                    {
                        Encoding = this.Encoding ?? Encoding.UTF8
                    }))
                    {
                        // Set FileAction (Overwirte or NOT)
                        ExtractExistingFileAction fileAction = this.Force ? ExtractExistingFileAction.OverwriteSilently : ExtractExistingFileAction.DoNotOverwrite;

                        // ProgressRecord (Main):
                        ProgressRecord mainProgress = new ProgressRecord(0, $"{this.MyInvocation.MyCommand}: '{src_zipfilepath}' を展開しています", "準備中...");

                        // ProgressRecord (Sub):
                        ProgressRecord subProgress = new ProgressRecord(1, "準備中...", "準備中...")
                        {
                            ParentActivityId = 0
                        };

                        // Register Event Handler only if needed
                        if (!this.SuppressProgress || !this.SuppressOutput || this.PassThru)
                        {
                            // Root Entries for Output
                            List <string> outputEntryRoots = new List <string>();

                            // Count(s)
                            int entryCount         = 0;
                            int eventCount         = 0;
                            int eventIntervalCount = 150;

                            // ZipFile.ExtractProgress Event Handler
                            zip.ExtractProgress += (object sender, ExtractProgressEventArgs e) =>
                            {
#if DEBUG
                                // DEBUG Output
                                this.WriteDebug("");
                                this.WriteDebug($"e.{nameof(e.EventType)} = {e.EventType}");
                                this.WriteDebug($"e.{nameof(e.ArchiveName)} = {e.ArchiveName}");
                                this.WriteDebug($"e.{nameof(e.BytesTransferred)} = {e.BytesTransferred}");
                                this.WriteDebug($"e.{nameof(e.TotalBytesToTransfer)} = {e.TotalBytesToTransfer}");
                                this.WriteDebug($"e.{nameof(e.EntriesTotal)} = {e.EntriesTotal}");
                                this.WriteDebug($"e.{nameof(e.CurrentEntry)} = {e.CurrentEntry}");
                                this.WriteDebug($"e.{nameof(e.EntriesExtracted)} = {e.EntriesExtracted}");
#endif

                                // for ProgressRecord(s)
                                if (!this.SuppressProgress)
                                {
                                    switch (e.EventType)
                                    {
                                    // Before Extracting Entry
                                    case ZipProgressEventType.Extracting_BeforeExtractEntry:

                                        // Increment count of Entry
                                        entryCount++;

                                        mainProgress.Activity = (zip.Count > 1) ?
                                                                $"{this.MyInvocation.MyCommand}: '{src_zipfilepath}' ({entryCount} / {zip.Count}) を展開しています" :
                                                                $"{this.MyInvocation.MyCommand}: '{src_zipfilepath}' を展開しています";

                                        mainProgress.StatusDescription = $"'{e.CurrentEntry.FileName}' を展開中...";
                                        mainProgress.PercentComplete   = 100 * (entryCount - 1) / zip.Count;

                                        // Write Progress (Main)
                                        this.WriteProgress(mainProgress);
                                        break;

                                    // Entry Bytes are written
                                    case ZipProgressEventType.Extracting_EntryBytesWritten:

                                        // Increment event count
                                        if (++eventCount > eventIntervalCount)
                                        {
                                            // UPDATE Progress (Main)
                                            mainProgress.StatusDescription = $"'{e.CurrentEntry.FileName}' ({e.BytesTransferred} / {e.TotalBytesToTransfer} バイト) を展開中...";
                                            mainProgress.PercentComplete   = ((100 * (entryCount - 1)) + (int)(100 * e.BytesTransferred / e.TotalBytesToTransfer)) / zip.Count;

                                            // Write Progress (Main)
                                            this.WriteProgress(mainProgress);

                                            // for Sub Progress
                                            if (this.MyInvocation.BoundParameters.ContainsKey("Verbose"))
                                            {
                                                // UPDATE Progress (Sub)
                                                subProgress.Activity          = $"'{e.CurrentEntry}' を展開しています";
                                                subProgress.StatusDescription = $"{e.BytesTransferred} / {e.TotalBytesToTransfer} バイトを展開中...";
                                                subProgress.PercentComplete   = (int)(100 * e.BytesTransferred / e.TotalBytesToTransfer);

                                                // Write Progress (Sub)
                                                this.WriteProgress(subProgress);
                                            }

                                            // Reset event count
                                            eventCount = 0;
                                        }
                                        break;

                                    default:
                                        break;
                                    }
                                }
                                // for ProgressRecord(s)

                                // for Entry Output
                                if (e.EventType == ZipProgressEventType.Extracting_AfterExtractEntry)
                                {
                                    if (this.PassThru)
                                    {
                                        // PassThru:

                                        // Convert '/' -> '\' (System.IO.Path.DirectorySeparatorChar)
                                        string filename = e.CurrentEntry.FileName.Replace('/', System.IO.Path.DirectorySeparatorChar);

                                        // Output
                                        if (e.CurrentEntry.IsDirectory)
                                        {
                                            // Directory:
                                            this.WriteObject(new DirectoryInfo(System.IO.Path.Combine(e.ExtractLocation, filename)));
                                        }
                                        else
                                        {
                                            // File:
                                            this.WriteObject(new FileInfo(System.IO.Path.Combine(e.ExtractLocation, filename)));
                                        }
                                    }
                                    else
                                    {
                                        // NOT PassThru:
                                        if (!this.SuppressOutput)
                                        {
                                            // NOT PassThru & NOT SuppressOutput:

                                            string[] separated = e.CurrentEntry.FileName.Split(new char[] { '/' });
                                            string   root      = separated[0];

                                            if (!outputEntryRoots.Contains(root))
                                            {
                                                // Add File Name of Root Entry
                                                outputEntryRoots.Add(root);

                                                // Output
                                                if (e.CurrentEntry.IsDirectory || (separated.Length > 1))
                                                {
                                                    // Directory:
                                                    this.WriteObject(new DirectoryInfo(System.IO.Path.Combine(dest_dirpath, root)));
                                                }
                                                else
                                                {
                                                    // File:
                                                    this.WriteObject(new FileInfo(System.IO.Path.Combine(dest_dirpath, root)));
                                                }
                                            }
                                        }
                                    }
                                }
                                // for Entry Output
                            };
                            // ZipFile.ExtractProgress Event Handler
                        }


                        // UnZip (Extract)
                        foreach (var entry in zip)
                        {
                            // Extract each Zip entries
                            if (string.IsNullOrEmpty(this.Password))
                            {
                                // w/o Password
                                entry.Extract(dest_dirpath, fileAction);
                            }
                            else
                            {
                                // with Password
                                entry.ExtractWithPassword(dest_dirpath, fileAction, this.Password);
                            }
                        }


                        // Completion of ProgressRecord(s):
                        foreach (var progress in new ProgressRecord[] { subProgress, mainProgress })
                        {
                            if (progress != null)
                            {
                                // Complete the Progress
                                progress.PercentComplete = 100;
                                progress.RecordType      = ProgressRecordType.Completed;

                                // Write Progress
                                this.WriteProgress(progress);
                            }
                        }
                    }
                    // using ZipFile
                }
                // Should Process
            }
        }
        // ----------------------------------------------------------------------------------------------------
        // Pre-Processing Operations
        // ----------------------------------------------------------------------------------------------------
        // (None)


        // ----------------------------------------------------------------------------------------------------
        // Input Processing Operations
        // ----------------------------------------------------------------------------------------------------
        protected override void ProcessRecord()
        {
            foreach (var src_paths in this.Path)
            {
                string dest_zipfilepath = null;

                foreach (var src_path in SessionLocation.GetResolvedPath(this.SessionState, src_paths))
                {
                    // SET Destination ZIP File Path
                    if (dest_zipfilepath is null)
                    {
                        // Destination ZIP File Path is not yet set.

                        // SET Destination ZIP File Path
                        dest_zipfilepath = this.DestinationPath is null?
                                           SessionLocation.GetUnresolvedPath(this.SessionState, System.IO.Path.GetFileNameWithoutExtension(src_path)) + ".zip" :
                                           SessionLocation.GetUnresolvedPath(this.SessionState, this.DestinationPath);

                        // Validation (Destination Path Existence Check: Directory):
                        if (Directory.Exists(dest_zipfilepath))
                        {
                            throw new IOException();
                        }

                        // Validation (Destination Path Existence Check: File):
                        if (File.Exists(dest_zipfilepath))
                        {
                            if (this.Force)
                            {
                                File.Delete(dest_zipfilepath);
                            }
                            else
                            {
                                throw new IOException();
                            }
                        }
                    }

                    // Should Process
                    if (this.ShouldProcess($"Source: '{src_path}', Destination:'{dest_zipfilepath}'", "ファイルの圧縮"))
                    {
                        // using ZipFile
                        using (ZipFile zip = new ZipFile(dest_zipfilepath, this.Encoding ?? Encoding.UTF8))
                        {
                            // SET Password
                            if (!string.IsNullOrEmpty(this.Password))
                            {
                                zip.Password = this.Password;
                            }

                            // SET ZIP64 extension
                            zip.UseZip64WhenSaving = Zip64Option.AsNecessary;

                            // Workaround of DotNetZip bug
                            zip.ParallelDeflateThreshold = -1;

                            // SET Flag for workaround not to save timestamp
                            zip.EmitTimesInWindowsFormatWhenSaving = false;
                            zip.EmitTimesInUnixFormatWhenSaving    = false;

                            // ProgressRecord (Main):
                            ProgressRecord mainProgress = new ProgressRecord(0, $"{this.MyInvocation.MyCommand}: '{src_path}' を圧縮しています", "準備中...");

                            // ProgressRecord (Sub):
                            ProgressRecord subProgress = new ProgressRecord(1, "準備中...", "準備中...")
                            {
                                ParentActivityId = 0
                            };

                            // Register Event Handler only if needed
                            if (!this.SuppressProgress)
                            {
                                // Count(s)
                                int entryCount         = 0;
                                int eventCount         = 0;
                                int eventIntervalCount = 150;

                                // ZipFile.ExtractProgress Event Handler
                                zip.SaveProgress += (object sender, SaveProgressEventArgs e) =>
                                {
#if DEBUG
                                    // DEBUG Output
                                    this.WriteDebug("");
                                    this.WriteDebug($"e.{nameof(e.EventType)} = {e.EventType}");
                                    this.WriteDebug($"e.{nameof(e.ArchiveName)} = {e.ArchiveName}");
                                    this.WriteDebug($"e.{nameof(e.BytesTransferred)} = {e.BytesTransferred}");
                                    this.WriteDebug($"e.{nameof(e.TotalBytesToTransfer)} = {e.TotalBytesToTransfer}");
                                    this.WriteDebug($"e.{nameof(e.EntriesTotal)} = {e.EntriesTotal}");
                                    this.WriteDebug($"e.{nameof(e.CurrentEntry)} = {e.CurrentEntry}");
                                    this.WriteDebug($"e.{nameof(e.EntriesSaved)} = {e.EntriesSaved}");
#endif

                                    // for ProgressRecord(s)
                                    switch (e.EventType)
                                    {
                                    case ZipProgressEventType.Saving_AfterWriteEntry:
                                        break;

                                    case ZipProgressEventType.Saving_EntryBytesRead:
                                        break;

                                    default:
                                        break;
                                    }

                                    switch (e.EventType)
                                    {
                                    // Before Write Entry
                                    case ZipProgressEventType.Saving_BeforeWriteEntry:

                                        // Increment count of Entry
                                        entryCount++;

                                        mainProgress.Activity = (zip.Count > 1) ?
                                                                $"{this.MyInvocation.MyCommand}: '{src_path}' ({entryCount} / {zip.Count}) を圧縮しています" :
                                                                $"{this.MyInvocation.MyCommand}: '{src_path}' を圧縮しています";

                                        mainProgress.StatusDescription = $"'{e.CurrentEntry.FileName}' を圧縮中...";
                                        mainProgress.PercentComplete   = 100 * (entryCount - 1) / zip.Count;

                                        // Write Progress (Main)
                                        this.WriteProgress(mainProgress);
                                        break;

                                    // Entry Bytes are read
                                    case ZipProgressEventType.Saving_EntryBytesRead:
                                        if (e.TotalBytesToTransfer != 0)
                                        {
                                            // Increment event count
                                            if (++eventCount > eventIntervalCount)
                                            {
                                                // UPDATE Progress (Main)
                                                mainProgress.StatusDescription = $"'{e.CurrentEntry.FileName}' ({e.BytesTransferred} / {e.TotalBytesToTransfer} バイト) を圧縮中...";
                                                mainProgress.PercentComplete   = ((100 * (entryCount - 1)) + (int)(100 * e.BytesTransferred / e.TotalBytesToTransfer)) / zip.Count;

                                                // Write Progress (Main)
                                                this.WriteProgress(mainProgress);

                                                // for Sub Progress
                                                if (this.MyInvocation.BoundParameters.ContainsKey("Verbose"))
                                                {
                                                    // UPDATE Progress (Sub)
                                                    subProgress.Activity          = $"'{e.CurrentEntry}' を圧縮しています";
                                                    subProgress.StatusDescription = $"{e.BytesTransferred} / {e.TotalBytesToTransfer} バイトを圧縮中...";
                                                    subProgress.PercentComplete   = (int)(100 * e.BytesTransferred / e.TotalBytesToTransfer);

                                                    // Write Progress (Sub)
                                                    this.WriteProgress(subProgress);
                                                }

                                                // Reset event count
                                                eventCount = 0;
                                            }
                                        }
                                        break;

                                    default:
                                        break;
                                    }
                                    // for ProgressRecord(s)
                                };
                                // ZipFile.ExtractProgress Event Handler
                            }


                            // Add to Zip (Archive)
                            if (File.Exists(src_path))
                            {
                                // File
                                zip.AddFile(src_path, string.Empty);
                            }
                            else if (Directory.Exists(src_path))
                            {
                                // Directory
                                zip.AddDirectory(src_path, new DirectoryInfo(src_path).Name);
                            }
                            else
                            {
                                throw new InvalidDataException();
                            }

                            // Save as file
                            zip.Save();


                            // Completion of ProgressRecord(s):
                            foreach (var progress in new ProgressRecord[] { subProgress, mainProgress })
                            {
                                if (progress != null)
                                {
                                    // Complete the Progress
                                    progress.PercentComplete = 100;
                                    progress.RecordType      = ProgressRecordType.Completed;

                                    // Write Progress
                                    this.WriteProgress(progress);
                                }
                            }


                            // Output (PassThru)
                            if (this.PassThru)
                            {
                                this.WriteObject(new FileInfo(dest_zipfilepath));
                            }
                        }
                        // using ZipFile
                    }
                    // Should Process
                }
            }
        }