jt
2021-06-10 5d0d028456874576560552f5a5c4e8b801786f11
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
// ZipFile.Extract.cs
// ------------------------------------------------------------------
//
// Copyright (c) 2009 Dino Chiesa.
// All rights reserved.
//
// This code module is part of DotNetZip, a zipfile class library.
//
// ------------------------------------------------------------------
//
// This code is licensed under the Microsoft Public License.
// See the file License.txt for the license details.
// More info on: http://dotnetzip.codeplex.com
//
// ------------------------------------------------------------------
//
// last saved (in emacs):
// Time-stamp: <2011-July-31 14:45:18>
//
// ------------------------------------------------------------------
//
// This module defines the methods for Extract operations on zip files.
//
// ------------------------------------------------------------------
//
 
 
using System;
using System.IO;
using System.Collections.Generic;
 
namespace HH.WMS.Utils.Ionic.Zip
{
 
    public partial class ZipFile
    {
 
        /// <summary>
        /// Extracts all of the items in the zip archive, to the specified path in the
        /// filesystem.  The path can be relative or fully-qualified.
        /// </summary>
        ///
        /// <remarks>
        /// <para>
        ///   This method will extract all entries in the <c>ZipFile</c> to the
        ///   specified path.
        /// </para>
        ///
        /// <para>
        ///   If an extraction of a file from the zip archive would overwrite an
        ///   existing file in the filesystem, the action taken is dictated by the
        ///   ExtractExistingFile property, which overrides any setting you may have
        ///   made on individual ZipEntry instances.  By default, if you have not
        ///   set that property on the <c>ZipFile</c> instance, the entry will not
        ///   be extracted, the existing file will not be overwritten and an
        ///   exception will be thrown. To change this, set the property, or use the
        ///   <see cref="ZipFile.ExtractAll(string,
        ///   HH.WMS.Utils.Ionic.Zip.ExtractExistingFileAction)" /> overload that allows you to
        ///   specify an ExtractExistingFileAction parameter.
        /// </para>
        ///
        /// <para>
        ///   The action to take when an extract would overwrite an existing file
        ///   applies to all entries.  If you want to set this on a per-entry basis,
        ///   then you must use one of the <see
        ///   cref="ZipEntry.Extract()">ZipEntry.Extract</see> methods.
        /// </para>
        ///
        /// <para>
        ///   This method will send verbose output messages to the <see
        ///   cref="StatusMessageTextWriter"/>, if it is set on the <c>ZipFile</c>
        ///   instance.
        /// </para>
        ///
        /// <para>
        /// You may wish to take advantage of the <c>ExtractProgress</c> event.
        /// </para>
        ///
        /// <para>
        ///   About timestamps: When extracting a file entry from a zip archive, the
        ///   extracted file gets the last modified time of the entry as stored in
        ///   the archive. The archive may also store extended file timestamp
        ///   information, including last accessed and created times. If these are
        ///   present in the <c>ZipEntry</c>, then the extracted file will also get
        ///   these times.
        /// </para>
        ///
        /// <para>
        ///   A Directory entry is somewhat different. It will get the times as
        ///   described for a file entry, but, if there are file entries in the zip
        ///   archive that, when extracted, appear in the just-created directory,
        ///   then when those file entries are extracted, the last modified and last
        ///   accessed times of the directory will change, as a side effect.  The
        ///   result is that after an extraction of a directory and a number of
        ///   files within the directory, the last modified and last accessed
        ///   timestamps on the directory will reflect the time that the last file
        ///   was extracted into the directory, rather than the time stored in the
        ///   zip archive for the directory.
        /// </para>
        ///
        /// <para>
        ///   To compensate, when extracting an archive with <c>ExtractAll</c>,
        ///   DotNetZip will extract all the file and directory entries as described
        ///   above, but it will then make a second pass on the directories, and
        ///   reset the times on the directories to reflect what is stored in the
        ///   zip archive.
        /// </para>
        ///
        /// <para>
        ///   This compensation is performed only within the context of an
        ///   <c>ExtractAll</c>. If you call <c>ZipEntry.Extract</c> on a directory
        ///   entry, the timestamps on directory in the filesystem will reflect the
        ///   times stored in the zip.  If you then call <c>ZipEntry.Extract</c> on
        ///   a file entry, which is extracted into the directory, the timestamps on
        ///   the directory will be updated to the current time.
        /// </para>
        /// </remarks>
        ///
        /// <example>
        ///   This example extracts all the entries in a zip archive file, to the
        ///   specified target directory.  The extraction will overwrite any
        ///   existing files silently.
        ///
        /// <code>
        /// String TargetDirectory= "unpack";
        /// using(ZipFile zip= ZipFile.Read(ZipFileToExtract))
        /// {
        ///     zip.ExtractExistingFile= ExtractExistingFileAction.OverwriteSilently;
        ///     zip.ExtractAll(TargetDirectory);
        /// }
        /// </code>
        ///
        /// <code lang="VB">
        /// Dim TargetDirectory As String = "unpack"
        /// Using zip As ZipFile = ZipFile.Read(ZipFileToExtract)
        ///     zip.ExtractExistingFile= ExtractExistingFileAction.OverwriteSilently
        ///     zip.ExtractAll(TargetDirectory)
        /// End Using
        /// </code>
        /// </example>
        ///
        /// <seealso cref="HH.WMS.Utils.Ionic.Zip.ZipFile.ExtractProgress"/>
        /// <seealso cref="HH.WMS.Utils.Ionic.Zip.ZipFile.ExtractExistingFile"/>
        ///
        /// <param name="path">
        ///   The path to which the contents of the zipfile will be extracted.
        ///   The path can be relative or fully-qualified.
        /// </param>
        ///
        public void ExtractAll(string path)
        {
            _InternalExtractAll(path, true);
        }
 
 
 
        /// <summary>
        /// Extracts all of the items in the zip archive, to the specified path in the
        /// filesystem, using the specified behavior when extraction would overwrite an
        /// existing file.
        /// </summary>
        ///
        /// <remarks>
        ///
        /// <para>
        /// This method will extract all entries in the <c>ZipFile</c> to the specified
        /// path.  For an extraction that would overwrite an existing file, the behavior
        /// is dictated by <paramref name="extractExistingFile"/>, which overrides any
        /// setting you may have made on individual ZipEntry instances.
        /// </para>
        ///
        /// <para>
        /// The action to take when an extract would overwrite an existing file
        /// applies to all entries.  If you want to set this on a per-entry basis,
        /// then you must use <see cref="ZipEntry.Extract(String,
        /// ExtractExistingFileAction)" /> or one of the similar methods.
        /// </para>
        ///
        /// <para>
        /// Calling this method is equivalent to setting the <see
        /// cref="ExtractExistingFile"/> property and then calling <see
        /// cref="ExtractAll(String)"/>.
        /// </para>
        ///
        /// <para>
        /// This method will send verbose output messages to the
        /// <see cref="StatusMessageTextWriter"/>, if it is set on the <c>ZipFile</c> instance.
        /// </para>
        /// </remarks>
        ///
        /// <example>
        /// This example extracts all the entries in a zip archive file, to the
        /// specified target directory.  It does not overwrite any existing files.
        /// <code>
        /// String TargetDirectory= "c:\\unpack";
        /// using(ZipFile zip= ZipFile.Read(ZipFileToExtract))
        /// {
        ///   zip.ExtractAll(TargetDirectory, ExtractExistingFileAction.DontOverwrite);
        /// }
        /// </code>
        ///
        /// <code lang="VB">
        /// Dim TargetDirectory As String = "c:\unpack"
        /// Using zip As ZipFile = ZipFile.Read(ZipFileToExtract)
        ///     zip.ExtractAll(TargetDirectory, ExtractExistingFileAction.DontOverwrite)
        /// End Using
        /// </code>
        /// </example>
        ///
        /// <param name="path">
        /// The path to which the contents of the zipfile will be extracted.
        /// The path can be relative or fully-qualified.
        /// </param>
        ///
        /// <param name="extractExistingFile">
        /// The action to take if extraction would overwrite an existing file.
        /// </param>
        /// <seealso cref="ExtractSelectedEntries(String,ExtractExistingFileAction)"/>
        public void ExtractAll(string path, ExtractExistingFileAction extractExistingFile)
        {
            ExtractExistingFile = extractExistingFile;
            _InternalExtractAll(path, true);
        }
 
 
        private void _InternalExtractAll(string path, bool overrideExtractExistingProperty)
        {
            bool header = Verbose;
            _inExtractAll = true;
            try
            {
                OnExtractAllStarted(path);
 
                int n = 0;
                foreach (ZipEntry e in _entries.Values)
                {
                    if (header)
                    {
                        StatusMessageTextWriter.WriteLine("\n{1,-22} {2,-8} {3,4}   {4,-8}  {0}",
                                  "Name", "Modified", "Size", "Ratio", "Packed");
                        StatusMessageTextWriter.WriteLine(new System.String('-', 72));
                        header = false;
                    }
                    if (Verbose)
                    {
                        StatusMessageTextWriter.WriteLine("{1,-22} {2,-8} {3,4:F0}%   {4,-8} {0}",
                                  e.FileName,
                                  e.LastModified.ToString("yyyy-MM-dd HH:mm:ss"),
                                  e.UncompressedSize,
                                  e.CompressionRatio,
                                  e.CompressedSize);
                        if (!String.IsNullOrEmpty(e.Comment))
                            StatusMessageTextWriter.WriteLine("  Comment: {0}", e.Comment);
                    }
                    e.Password = _Password;  // this may be null
                    OnExtractEntry(n, true, e, path);
                    if (overrideExtractExistingProperty)
                        e.ExtractExistingFile = this.ExtractExistingFile;
                    e.Extract(path);
                    n++;
                    OnExtractEntry(n, false, e, path);
                    if (_extractOperationCanceled)
                        break;
                }
 
                if (!_extractOperationCanceled)
                {
                    // workitem 8264:
                    // now, set times on directory entries, again.
                    // The problem is, extracting a file changes the times on the parent
                    // directory.  So after all files have been extracted, we have to
                    // run through the directories again.
                    foreach (ZipEntry e in _entries.Values)
                    {
                        // check if it is a directory
                        if ((e.IsDirectory) || (e.FileName.EndsWith("/")))
                        {
                            string outputFile = (e.FileName.StartsWith("/"))
                                ? Path.Combine(path, e.FileName.Substring(1))
                                : Path.Combine(path, e.FileName);
 
                            e._SetTimes(outputFile, false);
                        }
                    }
                    OnExtractAllCompleted(path);
                }
 
            }
            finally
            {
 
                _inExtractAll = false;
            }
        }
 
 
    }
}