ProjectArcade

Форк
0
202 строки · 7.0 Кб
1
using System;
2
using System.Collections.Generic;
3
using System.Linq;
4
using System.Text;
5
using System.IO;
6
using System.Runtime.InteropServices;
7

8
namespace EmulatorLauncher.Common.Compression
9
{
10
    public class ZipArchiveFileEntry
11
    {
12
        private object _entry;
13

14
        public ZipArchiveFileEntry(object zipArchiveEntry)
15
        {
16
            _entry = zipArchiveEntry;
17
        }
18

19
        public System.IO.Stream Open()
20
        {
21
            object obj = _entry.GetType().GetMethod("Open").Invoke(_entry, new object[] { });
22
            return obj as Stream;
23
        }
24

25
        public void Extract(string directory)
26
        {
27
            if (!Directory.Exists(directory))
28
                Directory.CreateDirectory(directory);
29

30
            string path = Path.Combine(directory, Filename);
31

32
            if (IsDirectory)
33
            {
34
                if (!Directory.Exists(path))
35
                    Directory.CreateDirectory(path);
36

37
                return;
38
            }
39

40
            using (var stream = Open())
41
            {
42
                if (stream == null)
43
                    return;
44

45
                bool canRetry = true;
46

47
                FileStream fileStream = null;
48

49
            retry:
50
                try
51
                {
52
                    fileStream = new FileStream(path, FileMode.Create, FileAccess.Write);
53
                }
54
                catch (IOException ex) 
55
                {
56
                    int errorCode = Marshal.GetHRForException(ex) & ((1 << 16) - 1);
57
                    if (canRetry && (errorCode == 32 || errorCode == 33))
58
                    {
59
                        canRetry = false;
60

61
                        try
62
                        {
63
                            string newName = Path.Combine(Path.GetDirectoryName(path), Path.GetFileName(path) + "_");
64
                            if (File.Exists(newName))
65
                                File.Delete(newName);
66

67
                            File.Move(path, newName);
68
                            goto retry;
69
                        }
70
                        catch { throw ex; }
71
                    }
72
                }
73

74
                if (fileStream != null)
75
                {
76
                    stream.CopyTo(fileStream);
77
                    fileStream.Dispose();
78
                }
79

80
                stream.Close();
81
            }
82
        }
83
        
84
        public string Filename { get; set; }
85
        public bool IsDirectory { get; set; }
86
        public long Length { get; set; }
87
        public DateTime LastModified { get; set; }
88
        public uint Crc32 { get; set; }
89

90
        public string HexCrc
91
        {
92
            get { return Crc32.ToString("x8"); }
93
        }
94

95
        public override string ToString()
96
        {
97
            return Filename;
98
        }
99
    }
100

101
    public class ZipArchive : IDisposable
102
    {
103
        private static System.Reflection.MethodInfo _zipCreateFromDirectory;
104

105
        public static void CreateFromDirectory(string sourceDirectoryName, string destinationArchiveFileName)
106
        {
107
            if (_zipCreateFromDirectory == null)
108
            {
109
                var afs = System.Reflection.Assembly.Load("System.IO.Compression.FileSystem, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
110
                if (afs == null)
111
                    throw new Exception("Framework not supported");
112

113
                var ass = System.Reflection.Assembly.Load("System.IO.Compression, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
114
                if (ass == null)
115
                    throw new Exception("Framework not supported");
116

117
                var zipFile = afs.GetTypes().FirstOrDefault(t => t.Name == "ZipFile");
118
                if (zipFile == null)
119
                    throw new Exception("Framework not supported");
120

121
                _zipCreateFromDirectory = zipFile.GetMember("CreateFromDirectory", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public).FirstOrDefault() as System.Reflection.MethodInfo;
122
                if (_zipCreateFromDirectory == null)
123
                    throw new Exception("Framework not supported");
124
            }
125

126
            _zipCreateFromDirectory.Invoke(null, new object[] { sourceDirectoryName, destinationArchiveFileName });            
127
        }
128

129
        private static System.Reflection.MethodInfo _zipOpenRead;
130

131
        private IDisposable _zipArchive;
132

133
        public static ZipArchive OpenRead(string path)
134
        {
135
            if (_zipOpenRead == null)
136
            {
137
                var afs = System.Reflection.Assembly.Load("System.IO.Compression.FileSystem, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
138
                if (afs == null)
139
                    throw new Exception("Framework not supported");
140

141
                var ass = System.Reflection.Assembly.Load("System.IO.Compression, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
142
                if (ass == null)
143
                    throw new Exception("Framework not supported");
144

145
                var zipFile = afs.GetTypes().FirstOrDefault(t => t.Name == "ZipFile");
146
                if (zipFile == null)
147
                    throw new Exception("Framework not supported");
148

149
                _zipOpenRead = zipFile.GetMember("OpenRead", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public).FirstOrDefault() as System.Reflection.MethodInfo;
150
                if (_zipOpenRead == null)
151
                    throw new Exception("Framework not supported");
152
            }
153

154

155
            IDisposable zipArchive = _zipOpenRead.Invoke(null, new object[] { path }) as IDisposable;
156
            if (zipArchive == null)
157
                return null;
158

159
            ZipArchive ret = new ZipArchive();
160
            ret._zipArchive = zipArchive;
161
            return ret;
162
        }
163

164

165
        public IEnumerable<ZipArchiveFileEntry> Entries
166
        {
167
            get
168
            {
169
                var entries = _zipArchive.GetType().GetValue<System.Collections.IEnumerable>(_zipArchive, "Entries");
170
                foreach (var entry in entries)
171
                {
172
                    var zipArchiveEntry = entry.GetType();
173

174
                    string fullName = zipArchiveEntry.GetValue<string>(entry, "FullName");
175
                    if (string.IsNullOrEmpty(fullName))
176
                        continue;
177

178
                    ZipArchiveFileEntry e = new ZipArchiveFileEntry(entry);
179
                    e.Filename = fullName;
180
                    e.Length = zipArchiveEntry.GetValue<long>(entry, "Length");
181
                    e.LastModified = zipArchiveEntry.GetValue<DateTimeOffset>(entry, "LastWriteTime").DateTime;
182
                    e.Crc32 = zipArchiveEntry.GetFieldValue<uint>(entry, "_crc32"); 
183

184
                    if (fullName.EndsWith("/"))
185
                    {
186
                        e.Filename = e.Filename.Substring(0, e.Filename.Length - 1);
187
                        e.IsDirectory = true;
188
                    }
189

190
                    yield return e;
191
                }
192
            }
193
        }
194

195
        public void Dispose()
196
        {
197
            if (_zipArchive != null)
198
                _zipArchive.Dispose();
199
        }
200
    }
201
       
202
}
203

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.