├── .gitignore ├── .idea └── .idea.SevenZipExtractor │ └── .idea │ ├── .gitignore │ ├── .name │ ├── encodings.xml │ ├── indexLayout.xml │ └── vcs.xml ├── Benchmark ├── Benchmark.csproj ├── Benchmarks.cs ├── Program.cs └── Resources │ └── 7z.7z ├── Example ├── Example.csproj └── Program.cs ├── LICENSE ├── Pack.ps1 ├── README.md ├── SevenZipExtractor.Tests ├── Crc32.cs ├── HashHelper.cs ├── Resources │ ├── 7z.7z │ ├── SevenZip.7z │ ├── ansimate-arj.arj │ ├── lzh.lzh │ ├── rar.rar │ ├── zip-hello.zip │ └── zip.zip ├── SevenZipExtractor.Tests.csproj ├── Test7Zip.cs ├── TestArj.cs ├── TestBase.cs ├── TestFileEntry.cs ├── TestFiles.Designer.cs ├── TestFiles.resx ├── TestLzh.cs ├── TestRar.cs └── TestZip.cs ├── SevenZipExtractor.sln └── SevenZipExtractor ├── ArchiveFile.cs ├── ArchiveFileCallback.cs ├── ArchiveStreamCallback.cs ├── ArchiveStreamsCallback.cs ├── Entry.cs ├── Formats.cs ├── IArchiveExtractCallback.cs ├── Kernel32Dll.cs ├── SafeLibraryHandle.cs ├── SevenZipException.cs ├── SevenZipExtractor.csproj ├── SevenZipExtractor.targets ├── SevenZipFormat.cs ├── SevenZipHandle.cs ├── SevenZipInterface.cs ├── x64 └── 7z.dll └── x86 └── 7z.dll /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | bld/ 21 | [Bb]in/ 22 | [Oo]bj/ 23 | 24 | # Do not ignore 7z.dll 25 | !/SevenZipExtractor/7zDll/x86/ 26 | !/SevenZipExtractor/7zDll/x64/ 27 | 28 | # Visual Studio 2015 cache/options directory 29 | .vs/ 30 | # Uncomment if you have tasks that create the project's static files in wwwroot 31 | #wwwroot/ 32 | 33 | # MSTest test Results 34 | [Tt]est[Rr]esult*/ 35 | [Bb]uild[Ll]og.* 36 | 37 | # NUNIT 38 | *.VisualState.xml 39 | TestResult.xml 40 | 41 | # Build Results of an ATL Project 42 | [Dd]ebugPS/ 43 | [Rr]eleasePS/ 44 | dlldata.c 45 | 46 | # DNX 47 | project.lock.json 48 | artifacts/ 49 | 50 | *_i.c 51 | *_p.c 52 | *_i.h 53 | *.ilk 54 | *.meta 55 | *.obj 56 | *.pch 57 | *.pdb 58 | *.pgc 59 | *.pgd 60 | *.rsp 61 | *.sbr 62 | *.tlb 63 | *.tli 64 | *.tlh 65 | *.tmp 66 | *.tmp_proj 67 | *.log 68 | *.vspscc 69 | *.vssscc 70 | .builds 71 | *.pidb 72 | *.svclog 73 | *.scc 74 | 75 | # Chutzpah Test files 76 | _Chutzpah* 77 | 78 | # Visual C++ cache files 79 | ipch/ 80 | *.aps 81 | *.ncb 82 | *.opendb 83 | *.opensdf 84 | *.sdf 85 | *.cachefile 86 | 87 | # Visual Studio profiler 88 | *.psess 89 | *.vsp 90 | *.vspx 91 | *.sap 92 | 93 | # TFS 2012 Local Workspace 94 | $tf/ 95 | 96 | # Guidance Automation Toolkit 97 | *.gpState 98 | 99 | # ReSharper is a .NET coding add-in 100 | _ReSharper*/ 101 | *.[Rr]e[Ss]harper 102 | *.DotSettings.user 103 | 104 | # JustCode is a .NET coding add-in 105 | .JustCode 106 | 107 | # TeamCity is a build add-in 108 | _TeamCity* 109 | 110 | # DotCover is a Code Coverage Tool 111 | *.dotCover 112 | 113 | # NCrunch 114 | _NCrunch_* 115 | .*crunch*.local.xml 116 | nCrunchTemp_* 117 | 118 | # MightyMoose 119 | *.mm.* 120 | AutoTest.Net/ 121 | 122 | # Web workbench (sass) 123 | .sass-cache/ 124 | 125 | # Installshield output folder 126 | [Ee]xpress/ 127 | 128 | # DocProject is a documentation generator add-in 129 | DocProject/buildhelp/ 130 | DocProject/Help/*.HxT 131 | DocProject/Help/*.HxC 132 | DocProject/Help/*.hhc 133 | DocProject/Help/*.hhk 134 | DocProject/Help/*.hhp 135 | DocProject/Help/Html2 136 | DocProject/Help/html 137 | 138 | # Click-Once directory 139 | publish/ 140 | 141 | # Publish Web Output 142 | *.[Pp]ublish.xml 143 | *.azurePubxml 144 | # TODO: Comment the next line if you want to checkin your web deploy settings 145 | # but database connection strings (with potential passwords) will be unencrypted 146 | *.pubxml 147 | *.publishproj 148 | 149 | # NuGet Packages 150 | *.nupkg 151 | # The packages folder can be ignored because of Package Restore 152 | **/packages/* 153 | # except build/, which is used as an MSBuild target. 154 | !**/packages/build/ 155 | # Uncomment if necessary however generally it will be regenerated when needed 156 | #!**/packages/repositories.config 157 | # NuGet v3's project.json files produces more ignoreable files 158 | *.nuget.props 159 | *.nuget.targets 160 | 161 | # Microsoft Azure Build Output 162 | csx/ 163 | *.build.csdef 164 | 165 | # Microsoft Azure Emulator 166 | ecf/ 167 | rcf/ 168 | 169 | # Microsoft Azure ApplicationInsights config file 170 | ApplicationInsights.config 171 | 172 | # Windows Store app package directory 173 | AppPackages/ 174 | BundleArtifacts/ 175 | 176 | # Visual Studio cache files 177 | # files ending in .cache can be ignored 178 | *.[Cc]ache 179 | # but keep track of directories ending in .cache 180 | !*.[Cc]ache/ 181 | 182 | # Others 183 | ClientBin/ 184 | ~$* 185 | *~ 186 | *.dbmdl 187 | *.dbproj.schemaview 188 | *.pfx 189 | *.publishsettings 190 | node_modules/ 191 | orleans.codegen.cs 192 | 193 | # RIA/Silverlight projects 194 | Generated_Code/ 195 | 196 | # Backup & report files from converting an old project file 197 | # to a newer Visual Studio version. Backup files are not needed, 198 | # because we have git ;-) 199 | _UpgradeReport_Files/ 200 | Backup*/ 201 | UpgradeLog*.XML 202 | UpgradeLog*.htm 203 | 204 | # SQL Server files 205 | *.mdf 206 | *.ldf 207 | 208 | # Business Intelligence projects 209 | *.rdl.data 210 | *.bim.layout 211 | *.bim_*.settings 212 | 213 | # Microsoft Fakes 214 | FakesAssemblies/ 215 | 216 | # GhostDoc plugin setting file 217 | *.GhostDoc.xml 218 | 219 | # Node.js Tools for Visual Studio 220 | .ntvs_analysis.dat 221 | 222 | # Visual Studio 6 build log 223 | *.plg 224 | 225 | # Visual Studio 6 workspace options file 226 | *.opt 227 | 228 | # Visual Studio LightSwitch build output 229 | **/*.HTMLClient/GeneratedArtifacts 230 | **/*.DesktopClient/GeneratedArtifacts 231 | **/*.DesktopClient/ModelManifest.xml 232 | **/*.Server/GeneratedArtifacts 233 | **/*.Server/ModelManifest.xml 234 | _Pvt_Extensions 235 | 236 | # Paket dependency manager 237 | .paket/paket.exe 238 | 239 | # FAKE - F# Make 240 | .fake/ 241 | -------------------------------------------------------------------------------- /.idea/.idea.SevenZipExtractor/.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Rider ignored files 5 | /projectSettingsUpdater.xml 6 | /.idea.SevenZipExtractor.iml 7 | /modules.xml 8 | /contentModel.xml 9 | # Datasource local storage ignored files 10 | /dataSources/ 11 | /dataSources.local.xml 12 | # Editor-based HTTP Client requests 13 | /httpRequests/ 14 | -------------------------------------------------------------------------------- /.idea/.idea.SevenZipExtractor/.idea/.name: -------------------------------------------------------------------------------- 1 | SevenZipExtractor -------------------------------------------------------------------------------- /.idea/.idea.SevenZipExtractor/.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/.idea.SevenZipExtractor/.idea/indexLayout.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/.idea.SevenZipExtractor/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Benchmark/Benchmark.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | Exe 4 | netcoreapp3.1;net47 5 | true 6 | Benchmark 7 | Benchmark 8 | Copyright © 2020 9 | bin\$(Configuration)\ 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | PreserveNewest 20 | 21 | 22 | -------------------------------------------------------------------------------- /Benchmark/Benchmarks.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | using System.Linq; 4 | using BenchmarkDotNet.Attributes; 5 | using BenchmarkDotNet.Configs; 6 | using BenchmarkDotNet.Diagnosers; 7 | using BenchmarkDotNet.Engines; 8 | using BenchmarkDotNet.Environments; 9 | using BenchmarkDotNet.Jobs; 10 | using SevenZipExtractor; 11 | 12 | namespace Benchmark 13 | { 14 | [Config(typeof(Config))] 15 | public class Benchmarks 16 | { 17 | private class Config : ManualConfig 18 | { 19 | public Config() 20 | { 21 | Add(MemoryDiagnoser.Default); 22 | Add(Job.ShortRun.With(ClrRuntime.Net47)); 23 | Add(Job.ShortRun.With(CoreRuntime.Core31)); 24 | } 25 | } 26 | 27 | const string ArchiveFileName = @"resources/7z.7z"; 28 | const string Directory = @"extracted"; 29 | 30 | private readonly string extractTo = Path.Combine(Directory, Path.GetFileNameWithoutExtension(ArchiveFileName)); 31 | private readonly Consumer consumer = new Consumer(); 32 | 33 | [GlobalSetup] 34 | public void GlobalSetup() 35 | { 36 | if (System.IO.Directory.Exists(Directory)) 37 | { 38 | System.IO.Directory.Delete(Directory, true); 39 | } 40 | System.IO.Directory.CreateDirectory(Directory); 41 | } 42 | 43 | // you can iterate over the entries in an archive and access their properties 44 | [Benchmark] 45 | public void PrintEntries() 46 | { 47 | using (ArchiveFile archiveFile = new ArchiveFile(ArchiveFileName)) 48 | { 49 | foreach (Entry entry in archiveFile.Entries) 50 | { 51 | if (entry.IsFolder) continue; 52 | consumer.Consume(entry.FileName); 53 | consumer.Consume(entry.Size); 54 | } 55 | } 56 | } 57 | 58 | // if you want to extract only a few entries from the archive 59 | // use the Entry.Extract method. 60 | [Benchmark] 61 | public void ExtractFirstEntry() 62 | { 63 | using (ArchiveFile archiveFile = new ArchiveFile(ArchiveFileName)) 64 | { 65 | Entry entry = archiveFile.Entries.First(x => !x.IsFolder); 66 | entry.Extract(Path.Combine(Directory, Path.GetFileName(entry.FileName))); 67 | } 68 | } 69 | 70 | // note that extracting the last entry is a lot slower than extracting 71 | // the first entry because 7-zip has to decompress the archive stream 72 | // to seek to the last entry 73 | [Benchmark] 74 | public void ExtractLastEntry() 75 | { 76 | using (ArchiveFile archiveFile = new ArchiveFile(ArchiveFileName)) 77 | { 78 | Entry entry = archiveFile.Entries.Last(x => !x.IsFolder); 79 | entry.Extract(Path.Combine(Directory, Path.GetFileName(entry.FileName))); 80 | } 81 | } 82 | 83 | // if you want to extract all entries from the archive, use ArchiveFile.Extract 84 | // this is a lot more performant than calling Extract on each entry individually 85 | [Benchmark] 86 | public void ExtractAll() 87 | { 88 | using (ArchiveFile archiveFile = new ArchiveFile(ArchiveFileName)) 89 | { 90 | archiveFile.Extract(extractTo, true); 91 | } 92 | } 93 | } 94 | } -------------------------------------------------------------------------------- /Benchmark/Program.cs: -------------------------------------------------------------------------------- 1 | using BenchmarkDotNet.Running; 2 | 3 | namespace Benchmark 4 | { 5 | class Program 6 | { 7 | static void Main(string[] args) => BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Benchmark/Resources/7z.7z: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adoconnection/SevenZipExtractor/95c469c9554ffa5218f8771ded9dc4b58dba8819/Benchmark/Resources/7z.7z -------------------------------------------------------------------------------- /Example/Example.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | Exe 4 | ConsoleApplication86 5 | ConsoleApplication86 6 | net45 7 | ConsoleApplication86 8 | ConsoleApplication86 9 | Copyright © 2016 10 | bin\$(Configuration)\ 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Example/Program.cs: -------------------------------------------------------------------------------- 1 |  2 | using System; 3 | using System.IO; 4 | using SevenZipExtractor; 5 | 6 | namespace ConsoleApplication86 7 | { 8 | class Program 9 | { 10 | static void Main(string[] args) 11 | { 12 | using (ArchiveFile archiveFile = new ArchiveFile(@"Archive.arj")) 13 | { 14 | // extract all 15 | archiveFile.Extract("Output"); 16 | } 17 | 18 | using (ArchiveFile archiveFile = new ArchiveFile("archive.arj")) 19 | { 20 | foreach (Entry entry in archiveFile.Entries) 21 | { 22 | Console.WriteLine(entry.FileName); 23 | 24 | // extract to file 25 | entry.Extract(entry.FileName); 26 | 27 | // extract to stream 28 | MemoryStream memoryStream = new MemoryStream(); 29 | entry.Extract(memoryStream); 30 | } 31 | } 32 | 33 | Console.WriteLine(""); 34 | Console.WriteLine("done"); 35 | Console.ReadKey(); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Alexander Selishchev 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Pack.ps1: -------------------------------------------------------------------------------- 1 | dotnet build -c Release 2 | dotnet test -c Release 3 | dotnet pack -c Release -o artifacts SevenZipExtractor\SevenZipExtractor.csproj 4 | dotnet nuget push artifacts\SevenZipExtractor.1.0.19.nupkg --source https://www.nuget.org/api/v2/package# h:\nuget pack H:\SevenZipExtractorGit\SevenZipExtractor\SevenZipExtractor\SevenZipExtractor.csproj -IncludeReferencedProjects -Prop Configuration=Release 5 | #h:\nuget push SevenZipExtractor.1.0.15.nupkg -Source https://www.nuget.org/api/v2/package 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SevenZipExtractor 2 | C# wrapper for 7z.dll (x86 and x64 included) 3 | - .NET Standard 2.0 4 | - .NET Framework 4.5 5 | 6 | [![NuGet](https://img.shields.io/nuget/dt/SevenZipExtractor.svg?style=flat-square)](https://www.nuget.org/packages/SevenZipExtractor) 7 | [![NuGet](https://img.shields.io/nuget/v/SevenZipExtractor.svg?style=flat-square)](https://www.nuget.org/packages/SevenZipExtractor) 8 | 9 | Every single star makes maintainer happy! ⭐ 10 | 11 | ## NuGet 12 | ``` 13 | Install-Package SevenZipExtractor 14 | ``` 15 | 16 | ## Supported formats: 17 | * 7Zip 18 | * APM 19 | * Arj 20 | * BZip2 21 | * Cab 22 | * Chm 23 | * Compound 24 | * Cpio 25 | * CramFS 26 | * Deb 27 | * Dll 28 | * Dmg 29 | * Exe 30 | * Fat 31 | * Flv 32 | * GZip 33 | * Hfs 34 | * Iso 35 | * Lzh 36 | * Lzma 37 | * Lzma86 38 | * Mach-O 39 | * Mbr 40 | * Mub 41 | * Nsis 42 | * Ntfs 43 | * Ppmd 44 | * Rar 45 | * Rar5 46 | * Rpm 47 | * Split 48 | * SquashFS 49 | * Swf 50 | * Swfc 51 | * Tar 52 | * TE 53 | * Udf 54 | * UEFIc 55 | * UEFIs 56 | * Vhd (?) 57 | * Wim 58 | * Xar 59 | * XZ 60 | * Z 61 | * Zip 62 | 63 | 64 | 65 | 66 | ## Examples 67 | 68 | #### Extract all 69 | ```cs 70 | using (ArchiveFile archiveFile = new ArchiveFile(@"Archive.ARJ")) 71 | { 72 | archiveFile.Extract("Output"); // extract all 73 | } 74 | ``` 75 | 76 | #### Extract password proceted archive, owerwrite files 77 | ```cs 78 | using (ArchiveFile archiveFile = new ArchiveFile(@"Archive.ARJ")) 79 | { 80 | archiveFile.Extract("Output", overwrite: true, password: "mySecret"); 81 | } 82 | ``` 83 | 84 | #### Extract to file or stream 85 | ```cs 86 | using (ArchiveFile archiveFile = new ArchiveFile(@"Archive.ARJ")) 87 | { 88 | foreach (Entry entry in archiveFile.Entries) 89 | { 90 | Console.WriteLine(entry.FileName); 91 | 92 | // extract to file 93 | entry.Extract(entry.FileName); 94 | 95 | // extract to stream 96 | MemoryStream memoryStream = new MemoryStream(); 97 | entry.Extract(memoryStream); 98 | } 99 | } 100 | 101 | ``` 102 | 103 | #### Guess archive format from files without extensions 104 | ```cs 105 | using (ArchiveFile archiveFile = new ArchiveFile(@"c:\random-archive")) 106 | { 107 | archiveFile.Extract("Output"); 108 | } 109 | ``` 110 | 111 | #### Guess archive format from streams 112 | ```cs 113 | WebRequest request = WebRequest.Create ("http://www.contoso.com/file.aspx?id=12345"); 114 | HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 115 | 116 | using (ArchiveFile archiveFile = new ArchiveFile(response.GetResponseStream()) 117 | { 118 | archiveFile.Extract("Output"); 119 | } 120 | ``` 121 | 122 | ## Wiki 123 | * [Extracting from solid archives](https://github.com/adoconnection/SevenZipExtractor/wiki/Extracting-from-solid-archives) 124 | * [Extract tar.gz, tag.xz](https://github.com/adoconnection/SevenZipExtractor/wiki/Extract-tar.gz,-tag.xz) 125 | 126 | 127 | 128 | ## 7z.dll 129 | 7z.dll (x86 and x64) will be added to your BIN folder automatically. 130 | 131 | 132 | ## License 133 | - Based on code from: http://www.codeproject.com/Articles/27148/C-NET-Interface-for-Zip-Archive-DLLs 134 | - Source code in this repo is licensed under The MIT License 135 | - 7z binaries license http://www.7-zip.org/license.txt 136 | 137 | 138 | 139 | ## Changelog 140 | 1.0.19 / 2024.12.18 141 | - Password property for archive.Extract method 142 | 143 | 1.0.18 / 2024.12.18 144 | - [Extract password protected archives](https://github.com/adoconnection/SevenZipExtractor/issues/77) (Thanks [SalmaBegumJSR](https://github.com/SalmaBegumJSR)) 145 | - #75 updating dlls to 24.08 version (Thanks [insane-abreu](https://github.com/insane-abreu)) 146 | - #69 Add exposed field that contains the archive format (Thanks [Gargaj](https://github.com/Gargaj)) 147 | 148 | 1.0.17 / 2022.04.08 149 | - #54 4Gb+ archives fixed! 🎉 (Thanks [Pyroluk](https://github.com/Pyroluk)) 150 | 151 | 1.0.16 / 2021.01.17 152 | - 7z binaries updated to 21.07.0.0 153 | - PR#56 - signature for ```SquashFS``` (Thanks [mmoosstt](https://github.com/mmoosstt)) 154 | - PR#53 - look for binaries in ```bin``` folder (Thanks [CupSunshine](https://github.com/CupSunshine)) 155 | 156 | 1.0.15 / 2020.01.14 157 | - .NETStandard 2.0 support PR#38 158 | 159 | 1.0.14 160 | - Entry.Extrat - preserveTimestamp is true by default #34 161 | - Dynamic operations can only be performed in homogenous AppDomain" #36 162 | -------------------------------------------------------------------------------- /SevenZipExtractor.Tests/Crc32.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Damien Guard. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 4 | 5 | // https://github.com/damieng/DamienGKit/blob/master/CSharp/DamienG.Library/Security/Cryptography/Crc32.cs 6 | 7 | using System; 8 | using System.Collections.Generic; 9 | using System.Security.Cryptography; 10 | 11 | namespace SevenZipExtractor.Tests 12 | { 13 | public sealed class Crc32 : HashAlgorithm 14 | { 15 | public const UInt32 DefaultPolynomial = 0xedb88320u; 16 | public const UInt32 DefaultSeed = 0xffffffffu; 17 | 18 | static UInt32[] defaultTable; 19 | 20 | readonly UInt32 seed; 21 | readonly UInt32[] table; 22 | UInt32 hash; 23 | 24 | public Crc32() 25 | : this(DefaultPolynomial, DefaultSeed) 26 | { 27 | } 28 | 29 | public Crc32(UInt32 polynomial, UInt32 seed) 30 | { 31 | if (!BitConverter.IsLittleEndian) 32 | throw new PlatformNotSupportedException("Not supported on Big Endian processors"); 33 | 34 | table = InitializeTable(polynomial); 35 | this.seed = hash = seed; 36 | } 37 | 38 | public override void Initialize() 39 | { 40 | hash = seed; 41 | } 42 | 43 | protected override void HashCore(byte[] array, int ibStart, int cbSize) 44 | { 45 | hash = CalculateHash(table, hash, array, ibStart, cbSize); 46 | } 47 | 48 | protected override byte[] HashFinal() 49 | { 50 | var hashBuffer = UInt32ToBigEndianBytes(~hash); 51 | HashValue = hashBuffer; 52 | return hashBuffer; 53 | } 54 | 55 | public override int HashSize { get { return 32; } } 56 | 57 | public static UInt32 Compute(byte[] buffer) 58 | { 59 | return Compute(DefaultSeed, buffer); 60 | } 61 | 62 | public static UInt32 Compute(UInt32 seed, byte[] buffer) 63 | { 64 | return Compute(DefaultPolynomial, seed, buffer); 65 | } 66 | 67 | public static UInt32 Compute(UInt32 polynomial, UInt32 seed, byte[] buffer) 68 | { 69 | return ~CalculateHash(InitializeTable(polynomial), seed, buffer, 0, buffer.Length); 70 | } 71 | 72 | static UInt32[] InitializeTable(UInt32 polynomial) 73 | { 74 | if (polynomial == DefaultPolynomial && defaultTable != null) 75 | return defaultTable; 76 | 77 | var createTable = new UInt32[256]; 78 | for (var i = 0; i < 256; i++) 79 | { 80 | var entry = (UInt32)i; 81 | for (var j = 0; j < 8; j++) 82 | if ((entry & 1) == 1) 83 | entry = (entry >> 1) ^ polynomial; 84 | else 85 | entry = entry >> 1; 86 | createTable[i] = entry; 87 | } 88 | 89 | if (polynomial == DefaultPolynomial) 90 | defaultTable = createTable; 91 | 92 | return createTable; 93 | } 94 | 95 | static UInt32 CalculateHash(UInt32[] table, UInt32 seed, IList buffer, int start, int size) 96 | { 97 | var hash = seed; 98 | for (var i = start; i < start + size; i++) 99 | hash = (hash >> 8) ^ table[buffer[i] ^ hash & 0xff]; 100 | return hash; 101 | } 102 | 103 | static byte[] UInt32ToBigEndianBytes(UInt32 uint32) 104 | { 105 | var result = BitConverter.GetBytes(uint32); 106 | 107 | if (BitConverter.IsLittleEndian) 108 | Array.Reverse(result); 109 | 110 | return result; 111 | } 112 | } 113 | } -------------------------------------------------------------------------------- /SevenZipExtractor.Tests/HashHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Security.Cryptography; 4 | using System.Text; 5 | 6 | namespace SevenZipExtractor.Tests 7 | { 8 | public static class HashHelper 9 | { 10 | public static string MD5String(this byte[] value) 11 | { 12 | byte[] hashBytes = (MD5.Create()).ComputeHash(value); 13 | StringBuilder builder = new StringBuilder(); 14 | 15 | foreach (byte hashByte in hashBytes) 16 | { 17 | builder.Append(hashByte.ToString("x2")); 18 | } 19 | 20 | return builder.ToString(); 21 | } 22 | public static string CRC32String(this byte[] value) 23 | { 24 | Crc32 crc32 = new Crc32(); 25 | string hash = string.Empty; 26 | 27 | foreach (byte b in crc32.ComputeHash(value)) 28 | { 29 | hash += b.ToString("x2").ToUpper(); 30 | } 31 | 32 | return hash; 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /SevenZipExtractor.Tests/Resources/7z.7z: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adoconnection/SevenZipExtractor/95c469c9554ffa5218f8771ded9dc4b58dba8819/SevenZipExtractor.Tests/Resources/7z.7z -------------------------------------------------------------------------------- /SevenZipExtractor.Tests/Resources/SevenZip.7z: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adoconnection/SevenZipExtractor/95c469c9554ffa5218f8771ded9dc4b58dba8819/SevenZipExtractor.Tests/Resources/SevenZip.7z -------------------------------------------------------------------------------- /SevenZipExtractor.Tests/Resources/ansimate-arj.arj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adoconnection/SevenZipExtractor/95c469c9554ffa5218f8771ded9dc4b58dba8819/SevenZipExtractor.Tests/Resources/ansimate-arj.arj -------------------------------------------------------------------------------- /SevenZipExtractor.Tests/Resources/lzh.lzh: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adoconnection/SevenZipExtractor/95c469c9554ffa5218f8771ded9dc4b58dba8819/SevenZipExtractor.Tests/Resources/lzh.lzh -------------------------------------------------------------------------------- /SevenZipExtractor.Tests/Resources/rar.rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adoconnection/SevenZipExtractor/95c469c9554ffa5218f8771ded9dc4b58dba8819/SevenZipExtractor.Tests/Resources/rar.rar -------------------------------------------------------------------------------- /SevenZipExtractor.Tests/Resources/zip-hello.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adoconnection/SevenZipExtractor/95c469c9554ffa5218f8771ded9dc4b58dba8819/SevenZipExtractor.Tests/Resources/zip-hello.zip -------------------------------------------------------------------------------- /SevenZipExtractor.Tests/Resources/zip.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adoconnection/SevenZipExtractor/95c469c9554ffa5218f8771ded9dc4b58dba8819/SevenZipExtractor.Tests/Resources/zip.zip -------------------------------------------------------------------------------- /SevenZipExtractor.Tests/SevenZipExtractor.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | net45 4 | {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 5 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 6 | $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages 7 | False 8 | UnitTest 9 | SevenZipExtractor.Tests 10 | SevenZipExtractor.Tests 11 | Copyright © 2019 12 | bin\$(Configuration)\ 13 | AnyCPU;x64;x86 14 | x64 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | True 27 | True 28 | TestFiles.resx 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | ResXFileCodeGenerator 45 | TestFiles.Designer.cs 46 | Resources 47 | 48 | 49 | -------------------------------------------------------------------------------- /SevenZipExtractor.Tests/Test7Zip.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.TestTools.UnitTesting; 2 | 3 | namespace SevenZipExtractor.Tests 4 | { 5 | [TestClass] 6 | public class Test7Zip : TestBase 7 | { 8 | // 7Z does not provide folder as entry, only files 9 | 10 | [TestMethod] 11 | public void TestGuessAndExtractToStream_OK() 12 | { 13 | this.TestExtractToStream(Resources.TestFiles.SevenZip, this.TestEntriesWithoutFolder); 14 | } 15 | 16 | 17 | [TestMethod] 18 | public void TestKnownFormatAndExtractToStream_OK() 19 | { 20 | this.TestExtractToStream(Resources.TestFiles.SevenZip, this.TestEntriesWithoutFolder, SevenZipFormat.SevenZip); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /SevenZipExtractor.Tests/TestArj.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | using System.Linq; 4 | using Microsoft.VisualStudio.TestTools.UnitTesting; 5 | 6 | namespace SevenZipExtractor.Tests 7 | { 8 | [TestClass] 9 | public class TestArj : TestBase 10 | { 11 | [TestMethod] 12 | public void Text_UnboxAndCast_OK() 13 | { 14 | IList testEntries = new List() 15 | { 16 | new TestFileEntry { Name = "AM.EXE", IsFolder = false, CRC32 = "4353180B"}, 17 | new TestFileEntry { Name = "ANSIMATE.DOC", IsFolder = false, CRC32 = "84DA9118"}, 18 | new TestFileEntry { Name = "READ_ME!.BAT", IsFolder = false, CRC32 = "882B88D0"}, 19 | new TestFileEntry { Name = "SEE.COM", IsFolder = false, CRC32 = "88E01284"}, 20 | }; 21 | 22 | this.TestExtractToStream(Resources.TestFiles.ansimate_arj, testEntries, SevenZipFormat.Arj); 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /SevenZipExtractor.Tests/TestBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using Microsoft.VisualStudio.TestTools.UnitTesting; 6 | 7 | namespace SevenZipExtractor.Tests 8 | { 9 | public abstract class TestBase 10 | { 11 | protected IList TestEntriesWithFolder = new List() 12 | { 13 | new TestFileEntry { Name = "image1.jpg", IsFolder = false, MD5 = "b3144b66569ab0052b4019a2b4c07a31"}, 14 | new TestFileEntry { Name = "image2.jpg", IsFolder = false, MD5 = "8fdd4013edcf04b335ac3a9ce0c13887"}, 15 | new TestFileEntry { Name = "testFolder", IsFolder = true}, 16 | new TestFileEntry { Name = "testFolder\\image3.jpg", IsFolder = false, MD5 = "24ffd227340432596fe61ef6300098ad"}, 17 | }; 18 | 19 | protected IList TestEntriesWithoutFolder = new List() 20 | { 21 | new TestFileEntry { Name = "image1.jpg", IsFolder = false, MD5 = "b3144b66569ab0052b4019a2b4c07a31"}, 22 | new TestFileEntry { Name = "image2.jpg", IsFolder = false, MD5 = "8fdd4013edcf04b335ac3a9ce0c13887"}, 23 | new TestFileEntry { Name = "testFolder\\image3.jpg", IsFolder = false, MD5 = "24ffd227340432596fe61ef6300098ad"}, 24 | }; 25 | 26 | protected void TestExtractToStream(byte[] archiveBytes, IList expected, SevenZipFormat? sevenZipFormat = null, string password = null) 27 | { 28 | MemoryStream memoryStream = new MemoryStream(archiveBytes); 29 | 30 | using (ArchiveFile archiveFile = new ArchiveFile(memoryStream, sevenZipFormat)) 31 | { 32 | foreach (TestFileEntry testEntry in expected) 33 | { 34 | Entry entry = archiveFile.Entries.FirstOrDefault(e => e.FileName == testEntry.Name && e.IsFolder == testEntry.IsFolder); 35 | 36 | Assert.IsNotNull(entry, "Entry not found: " + testEntry.Name); 37 | 38 | if (testEntry.IsFolder) 39 | { 40 | continue; 41 | } 42 | 43 | using (MemoryStream entryMemoryStream = new MemoryStream()) 44 | { 45 | entry.Extract(entryMemoryStream, password); 46 | 47 | if (testEntry.MD5 != null) 48 | { 49 | Assert.AreEqual(testEntry.MD5, entryMemoryStream.ToArray().MD5String(), "MD5 does not match: " + entry.FileName); 50 | } 51 | 52 | if (testEntry.CRC32 != null) 53 | { 54 | Assert.AreEqual(testEntry.CRC32, entryMemoryStream.ToArray().CRC32String(), "CRC32 does not match: " + entry.FileName); 55 | } 56 | } 57 | } 58 | } 59 | 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /SevenZipExtractor.Tests/TestFileEntry.cs: -------------------------------------------------------------------------------- 1 | namespace SevenZipExtractor.Tests 2 | { 3 | public struct TestFileEntry 4 | { 5 | public string Name { get; set; } 6 | public bool IsFolder { get; set; } 7 | public string MD5 { get; set; } 8 | public string CRC32 { get; set; } 9 | } 10 | } -------------------------------------------------------------------------------- /SevenZipExtractor.Tests/TestFiles.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Resources { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class TestFiles { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal TestFiles() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SevenZipExtractor.Tests.TestFiles", typeof(TestFiles).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | /// 64 | /// Looks up a localized resource of type System.Byte[]. 65 | /// 66 | internal static byte[] ansimate_arj { 67 | get { 68 | object obj = ResourceManager.GetObject("ansimate_arj", resourceCulture); 69 | return ((byte[])(obj)); 70 | } 71 | } 72 | 73 | /// 74 | /// Looks up a localized resource of type System.Byte[]. 75 | /// 76 | internal static byte[] lzh { 77 | get { 78 | object obj = ResourceManager.GetObject("lzh", resourceCulture); 79 | return ((byte[])(obj)); 80 | } 81 | } 82 | 83 | /// 84 | /// Looks up a localized resource of type System.Byte[]. 85 | /// 86 | internal static byte[] rar { 87 | get { 88 | object obj = ResourceManager.GetObject("rar", resourceCulture); 89 | return ((byte[])(obj)); 90 | } 91 | } 92 | 93 | /// 94 | /// Looks up a localized resource of type System.Byte[]. 95 | /// 96 | internal static byte[] SevenZip { 97 | get { 98 | object obj = ResourceManager.GetObject("SevenZip", resourceCulture); 99 | return ((byte[])(obj)); 100 | } 101 | } 102 | 103 | /// 104 | /// Looks up a localized resource of type System.Byte[]. 105 | /// 106 | internal static byte[] zip { 107 | get { 108 | object obj = ResourceManager.GetObject("zip", resourceCulture); 109 | return ((byte[])(obj)); 110 | } 111 | } 112 | 113 | /// 114 | /// Looks up a localized resource of type System.Byte[]. 115 | /// 116 | internal static byte[] zip_hello { 117 | get { 118 | object obj = ResourceManager.GetObject("zip_hello", resourceCulture); 119 | return ((byte[])(obj)); 120 | } 121 | } 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /SevenZipExtractor.Tests/TestFiles.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 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 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 122 | Resources\ansimate-arj.arj;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 123 | 124 | 125 | Resources\lzh.lzh;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 126 | 127 | 128 | Resources\rar.rar;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 129 | 130 | 131 | Resources\SevenZip.7z;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 132 | 133 | 134 | Resources\zip.zip;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 135 | 136 | 137 | Resources\zip-hello.zip;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 138 | 139 | -------------------------------------------------------------------------------- /SevenZipExtractor.Tests/TestLzh.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.TestTools.UnitTesting; 2 | 3 | namespace SevenZipExtractor.Tests 4 | { 5 | [TestClass] 6 | public class TestLzh : TestBase 7 | { 8 | // LZH does not provide folder as entry, only files 9 | 10 | [TestMethod] 11 | public void TestGuessAndExtractToStream_Fails() 12 | { 13 | Assert.ThrowsException(() => 14 | { 15 | this.TestExtractToStream(Resources.TestFiles.lzh, this.TestEntriesWithoutFolder); 16 | }); 17 | } 18 | 19 | [TestMethod] 20 | public void TestKnownFormatAndExtractToStream_OK() 21 | { 22 | this.TestExtractToStream(Resources.TestFiles.lzh, this.TestEntriesWithoutFolder, SevenZipFormat.Lzh); 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /SevenZipExtractor.Tests/TestRar.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.TestTools.UnitTesting; 2 | 3 | namespace SevenZipExtractor.Tests 4 | { 5 | [TestClass] 6 | public class TestRar : TestBase 7 | { 8 | [TestMethod] 9 | public void TestGuessAndExtractToStream_OK() 10 | { 11 | this.TestExtractToStream(Resources.TestFiles.rar, this.TestEntriesWithFolder); 12 | } 13 | 14 | [TestMethod] 15 | public void TestKnownFormatAndExtractToStream_OK() 16 | { 17 | this.TestExtractToStream(Resources.TestFiles.rar, this.TestEntriesWithFolder, SevenZipFormat.Rar5); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /SevenZipExtractor.Tests/TestZip.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.TestTools.UnitTesting; 2 | 3 | namespace SevenZipExtractor.Tests 4 | { 5 | [TestClass] 6 | public class TestZip : TestBase 7 | { 8 | [TestMethod] 9 | public void TestGuessAndExtractToStream_OK() 10 | { 11 | this.TestExtractToStream(Resources.TestFiles.zip, this.TestEntriesWithFolder); 12 | } 13 | 14 | [TestMethod] 15 | public void TestKnownFormatAndExtractToStream_OK() 16 | { 17 | this.TestExtractToStream(Resources.TestFiles.zip, this.TestEntriesWithFolder, SevenZipFormat.Zip); 18 | } 19 | 20 | [TestMethod] 21 | public void TestKnownFormatAndExtractToStream_WithPassword_OK() 22 | { 23 | this.TestExtractToStream(Resources.TestFiles.zip_hello, this.TestEntriesWithFolder, SevenZipFormat.Zip, "hello"); 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /SevenZipExtractor.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.0.31903.59 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SevenZipExtractor", "SevenZipExtractor\SevenZipExtractor.csproj", "{8AA97F58-5044-4BBA-B8D9-A74B6947A660}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Example", "Example\Example.csproj", "{2EFA3756-853D-4282-A528-C644411112F3}" 9 | EndProject 10 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{2B48D535-FDC4-4C44-8C66-58A0B5049232}" 11 | ProjectSection(SolutionItems) = preProject 12 | Pack.ps1 = Pack.ps1 13 | EndProjectSection 14 | EndProject 15 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Benchmark", "Benchmark\Benchmark.csproj", "{49BCF38D-DAF5-42A5-BC77-B36820FB85FA}" 16 | EndProject 17 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SevenZipExtractor.Tests", "SevenZipExtractor.Tests\SevenZipExtractor.Tests.csproj", "{AF401731-D84B-46B3-8542-9E2FFA239D82}" 18 | EndProject 19 | Global 20 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 21 | Debug|Any CPU = Debug|Any CPU 22 | Debug|x64 = Debug|x64 23 | Debug|x86 = Debug|x86 24 | Release|Any CPU = Release|Any CPU 25 | Release|x64 = Release|x64 26 | Release|x86 = Release|x86 27 | EndGlobalSection 28 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 29 | {8AA97F58-5044-4BBA-B8D9-A74B6947A660}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 30 | {8AA97F58-5044-4BBA-B8D9-A74B6947A660}.Debug|Any CPU.Build.0 = Debug|Any CPU 31 | {8AA97F58-5044-4BBA-B8D9-A74B6947A660}.Debug|x64.ActiveCfg = Debug|Any CPU 32 | {8AA97F58-5044-4BBA-B8D9-A74B6947A660}.Debug|x64.Build.0 = Debug|Any CPU 33 | {8AA97F58-5044-4BBA-B8D9-A74B6947A660}.Debug|x86.ActiveCfg = Debug|Any CPU 34 | {8AA97F58-5044-4BBA-B8D9-A74B6947A660}.Debug|x86.Build.0 = Debug|Any CPU 35 | {8AA97F58-5044-4BBA-B8D9-A74B6947A660}.Release|Any CPU.ActiveCfg = Release|Any CPU 36 | {8AA97F58-5044-4BBA-B8D9-A74B6947A660}.Release|Any CPU.Build.0 = Release|Any CPU 37 | {8AA97F58-5044-4BBA-B8D9-A74B6947A660}.Release|x64.ActiveCfg = Release|Any CPU 38 | {8AA97F58-5044-4BBA-B8D9-A74B6947A660}.Release|x64.Build.0 = Release|Any CPU 39 | {8AA97F58-5044-4BBA-B8D9-A74B6947A660}.Release|x86.ActiveCfg = Release|Any CPU 40 | {8AA97F58-5044-4BBA-B8D9-A74B6947A660}.Release|x86.Build.0 = Release|Any CPU 41 | {2EFA3756-853D-4282-A528-C644411112F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 42 | {2EFA3756-853D-4282-A528-C644411112F3}.Debug|Any CPU.Build.0 = Debug|Any CPU 43 | {2EFA3756-853D-4282-A528-C644411112F3}.Debug|x64.ActiveCfg = Debug|Any CPU 44 | {2EFA3756-853D-4282-A528-C644411112F3}.Debug|x64.Build.0 = Debug|Any CPU 45 | {2EFA3756-853D-4282-A528-C644411112F3}.Debug|x86.ActiveCfg = Debug|Any CPU 46 | {2EFA3756-853D-4282-A528-C644411112F3}.Debug|x86.Build.0 = Debug|Any CPU 47 | {2EFA3756-853D-4282-A528-C644411112F3}.Release|Any CPU.ActiveCfg = Release|Any CPU 48 | {2EFA3756-853D-4282-A528-C644411112F3}.Release|Any CPU.Build.0 = Release|Any CPU 49 | {2EFA3756-853D-4282-A528-C644411112F3}.Release|x64.ActiveCfg = Release|Any CPU 50 | {2EFA3756-853D-4282-A528-C644411112F3}.Release|x64.Build.0 = Release|Any CPU 51 | {2EFA3756-853D-4282-A528-C644411112F3}.Release|x86.ActiveCfg = Release|Any CPU 52 | {2EFA3756-853D-4282-A528-C644411112F3}.Release|x86.Build.0 = Release|Any CPU 53 | {49BCF38D-DAF5-42A5-BC77-B36820FB85FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 54 | {49BCF38D-DAF5-42A5-BC77-B36820FB85FA}.Debug|Any CPU.Build.0 = Debug|Any CPU 55 | {49BCF38D-DAF5-42A5-BC77-B36820FB85FA}.Debug|x64.ActiveCfg = Debug|Any CPU 56 | {49BCF38D-DAF5-42A5-BC77-B36820FB85FA}.Debug|x64.Build.0 = Debug|Any CPU 57 | {49BCF38D-DAF5-42A5-BC77-B36820FB85FA}.Debug|x86.ActiveCfg = Debug|Any CPU 58 | {49BCF38D-DAF5-42A5-BC77-B36820FB85FA}.Debug|x86.Build.0 = Debug|Any CPU 59 | {49BCF38D-DAF5-42A5-BC77-B36820FB85FA}.Release|Any CPU.ActiveCfg = Release|Any CPU 60 | {49BCF38D-DAF5-42A5-BC77-B36820FB85FA}.Release|Any CPU.Build.0 = Release|Any CPU 61 | {49BCF38D-DAF5-42A5-BC77-B36820FB85FA}.Release|x64.ActiveCfg = Release|Any CPU 62 | {49BCF38D-DAF5-42A5-BC77-B36820FB85FA}.Release|x64.Build.0 = Release|Any CPU 63 | {49BCF38D-DAF5-42A5-BC77-B36820FB85FA}.Release|x86.ActiveCfg = Release|Any CPU 64 | {49BCF38D-DAF5-42A5-BC77-B36820FB85FA}.Release|x86.Build.0 = Release|Any CPU 65 | {AF401731-D84B-46B3-8542-9E2FFA239D82}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 66 | {AF401731-D84B-46B3-8542-9E2FFA239D82}.Debug|Any CPU.Build.0 = Debug|Any CPU 67 | {AF401731-D84B-46B3-8542-9E2FFA239D82}.Debug|x64.ActiveCfg = Debug|x64 68 | {AF401731-D84B-46B3-8542-9E2FFA239D82}.Debug|x64.Build.0 = Debug|x64 69 | {AF401731-D84B-46B3-8542-9E2FFA239D82}.Debug|x86.ActiveCfg = Debug|x86 70 | {AF401731-D84B-46B3-8542-9E2FFA239D82}.Debug|x86.Build.0 = Debug|x86 71 | {AF401731-D84B-46B3-8542-9E2FFA239D82}.Release|Any CPU.ActiveCfg = Release|Any CPU 72 | {AF401731-D84B-46B3-8542-9E2FFA239D82}.Release|Any CPU.Build.0 = Release|Any CPU 73 | {AF401731-D84B-46B3-8542-9E2FFA239D82}.Release|x64.ActiveCfg = Release|x64 74 | {AF401731-D84B-46B3-8542-9E2FFA239D82}.Release|x64.Build.0 = Release|x64 75 | {AF401731-D84B-46B3-8542-9E2FFA239D82}.Release|x86.ActiveCfg = Release|x86 76 | {AF401731-D84B-46B3-8542-9E2FFA239D82}.Release|x86.Build.0 = Release|x86 77 | EndGlobalSection 78 | GlobalSection(SolutionProperties) = preSolution 79 | HideSolutionNode = FALSE 80 | EndGlobalSection 81 | GlobalSection(ExtensibilityGlobals) = postSolution 82 | SolutionGuid = {FA02D714-896D-4F06-A15B-33EA2C628E63} 83 | EndGlobalSection 84 | EndGlobal 85 | -------------------------------------------------------------------------------- /SevenZipExtractor/ArchiveFile.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Runtime.InteropServices; 6 | 7 | namespace SevenZipExtractor 8 | { 9 | public class ArchiveFile : IDisposable 10 | { 11 | private SevenZipHandle sevenZipHandle; 12 | private readonly IInArchive archive; 13 | private readonly InStreamWrapper archiveStream; 14 | private IList entries; 15 | 16 | private string libraryFilePath; 17 | 18 | public SevenZipFormat Format { get; private set; } 19 | 20 | public ArchiveFile(string archiveFilePath, string libraryFilePath = null) 21 | { 22 | this.libraryFilePath = libraryFilePath; 23 | 24 | this.InitializeAndValidateLibrary(); 25 | 26 | if (!File.Exists(archiveFilePath)) 27 | { 28 | throw new SevenZipException("Archive file not found"); 29 | } 30 | 31 | SevenZipFormat format; 32 | 33 | string extension = Path.GetExtension(archiveFilePath); 34 | 35 | if (this.GuessFormatFromExtension(extension, out format)) 36 | { 37 | // great 38 | } 39 | else if (this.GuessFormatFromSignature(archiveFilePath, out format)) 40 | { 41 | // success 42 | } 43 | else 44 | { 45 | throw new SevenZipException(Path.GetFileName(archiveFilePath) + " is not a known archive type"); 46 | } 47 | 48 | this.Format = format; 49 | 50 | this.archive = this.sevenZipHandle.CreateInArchive(Formats.FormatGuidMapping[format]); 51 | this.archiveStream = new InStreamWrapper(File.OpenRead(archiveFilePath)); 52 | } 53 | 54 | public ArchiveFile(Stream archiveStream, SevenZipFormat? format = null, string libraryFilePath = null) 55 | { 56 | this.libraryFilePath = libraryFilePath; 57 | 58 | this.InitializeAndValidateLibrary(); 59 | 60 | if (archiveStream == null) 61 | { 62 | throw new SevenZipException("archiveStream is null"); 63 | } 64 | 65 | if (format == null) 66 | { 67 | SevenZipFormat guessedFormat; 68 | 69 | if (this.GuessFormatFromSignature(archiveStream, out guessedFormat)) 70 | { 71 | format = guessedFormat; 72 | } 73 | else 74 | { 75 | throw new SevenZipException("Unable to guess format automatically"); 76 | } 77 | } 78 | 79 | this.Format = format.Value; 80 | 81 | this.archive = this.sevenZipHandle.CreateInArchive(Formats.FormatGuidMapping[format.Value]); 82 | this.archiveStream = new InStreamWrapper(archiveStream); 83 | } 84 | 85 | 86 | public void Extract(string outputFolder, bool overwrite = false, string password = null) 87 | { 88 | this.Extract(entry => 89 | { 90 | string fileName = Path.Combine(outputFolder, entry.FileName); 91 | 92 | if (entry.IsFolder) 93 | { 94 | return fileName; 95 | } 96 | 97 | if (!File.Exists(fileName) || overwrite) 98 | { 99 | return fileName; 100 | } 101 | 102 | return null; 103 | }, 104 | password); 105 | } 106 | 107 | public void Extract(Func getOutputPath, string password = null) 108 | { 109 | IList fileStreams = new List(); 110 | 111 | try 112 | { 113 | foreach (Entry entry in this.Entries) 114 | { 115 | string outputPath = getOutputPath(entry); 116 | 117 | if (outputPath == null) // getOutputPath = null means SKIP 118 | { 119 | fileStreams.Add(null); 120 | continue; 121 | } 122 | 123 | if (entry.IsFolder) 124 | { 125 | Directory.CreateDirectory(outputPath); 126 | fileStreams.Add(null); 127 | continue; 128 | } 129 | 130 | string directoryName = Path.GetDirectoryName(outputPath); 131 | 132 | if (!string.IsNullOrWhiteSpace(directoryName)) 133 | { 134 | Directory.CreateDirectory(directoryName); 135 | } 136 | 137 | fileStreams.Add(File.Create(outputPath)); 138 | } 139 | 140 | this.archive.Extract(null, 0xFFFFFFFF, 0, new ArchiveStreamsCallback(fileStreams, password)); 141 | } 142 | finally 143 | { 144 | foreach (Stream stream in fileStreams) 145 | { 146 | if (stream != null) 147 | { 148 | stream.Dispose(); 149 | } 150 | } 151 | } 152 | } 153 | 154 | public IList Entries 155 | { 156 | get 157 | { 158 | if (this.entries != null) 159 | { 160 | return this.entries; 161 | } 162 | 163 | ulong checkPos = 32 * 1024; 164 | int open = this.archive.Open(this.archiveStream, ref checkPos, null); 165 | 166 | if (open != 0) 167 | { 168 | throw new SevenZipException("Unable to open archive"); 169 | } 170 | 171 | uint itemsCount = this.archive.GetNumberOfItems(); 172 | 173 | this.entries = new List(); 174 | 175 | for (uint fileIndex = 0; fileIndex < itemsCount; fileIndex++) 176 | { 177 | string fileName = this.GetProperty(fileIndex, ItemPropId.kpidPath); 178 | bool isFolder = this.GetProperty(fileIndex, ItemPropId.kpidIsFolder); 179 | bool isEncrypted = this.GetProperty(fileIndex, ItemPropId.kpidEncrypted); 180 | ulong size = this.GetProperty(fileIndex, ItemPropId.kpidSize); 181 | ulong packedSize = this.GetProperty(fileIndex, ItemPropId.kpidPackedSize); 182 | DateTime creationTime = this.GetPropertySafe(fileIndex, ItemPropId.kpidCreationTime); 183 | DateTime lastWriteTime = this.GetPropertySafe(fileIndex, ItemPropId.kpidLastWriteTime); 184 | DateTime lastAccessTime = this.GetPropertySafe(fileIndex, ItemPropId.kpidLastAccessTime); 185 | uint crc = this.GetPropertySafe(fileIndex, ItemPropId.kpidCRC); 186 | uint attributes = this.GetPropertySafe(fileIndex, ItemPropId.kpidAttributes); 187 | string comment = this.GetPropertySafe(fileIndex, ItemPropId.kpidComment); 188 | string hostOS = this.GetPropertySafe(fileIndex, ItemPropId.kpidHostOS); 189 | string method = this.GetPropertySafe(fileIndex, ItemPropId.kpidMethod); 190 | 191 | bool isSplitBefore = this.GetPropertySafe(fileIndex, ItemPropId.kpidSplitBefore); 192 | bool isSplitAfter = this.GetPropertySafe(fileIndex, ItemPropId.kpidSplitAfter); 193 | 194 | this.entries.Add(new Entry(this.archive, fileIndex) 195 | { 196 | FileName = fileName, 197 | IsFolder = isFolder, 198 | IsEncrypted = isEncrypted, 199 | Size = size, 200 | PackedSize = packedSize, 201 | CreationTime = creationTime, 202 | LastWriteTime = lastWriteTime, 203 | LastAccessTime = lastAccessTime, 204 | CRC = crc, 205 | Attributes = attributes, 206 | Comment = comment, 207 | HostOS = hostOS, 208 | Method = method, 209 | IsSplitBefore = isSplitBefore, 210 | IsSplitAfter = isSplitAfter 211 | }); 212 | } 213 | 214 | return this.entries; 215 | } 216 | } 217 | 218 | private T GetPropertySafe(uint fileIndex, ItemPropId name) 219 | { 220 | try 221 | { 222 | return this.GetProperty(fileIndex, name); 223 | } 224 | catch (InvalidCastException) 225 | { 226 | return default(T); 227 | } 228 | } 229 | 230 | private T GetProperty(uint fileIndex, ItemPropId name) 231 | { 232 | PropVariant propVariant = new PropVariant(); 233 | this.archive.GetProperty(fileIndex, name, ref propVariant); 234 | object value = propVariant.GetObject(); 235 | 236 | if (propVariant.VarType == VarEnum.VT_EMPTY) 237 | { 238 | propVariant.Clear(); 239 | return default(T); 240 | } 241 | 242 | propVariant.Clear(); 243 | 244 | if (value == null) 245 | { 246 | return default(T); 247 | } 248 | 249 | Type type = typeof(T); 250 | bool isNullable = type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>); 251 | Type underlyingType = isNullable ? Nullable.GetUnderlyingType(type) : type; 252 | 253 | // This is a hacky code just to work on Lex's machine 254 | if (underlyingType == typeof(DateTime)) 255 | { 256 | var dateTimeValue = (DateTime)value; 257 | return (T)(object)dateTimeValue; 258 | } 259 | 260 | T result = (T)Convert.ChangeType(value.ToString(), underlyingType); 261 | 262 | return result; 263 | } 264 | 265 | private void InitializeAndValidateLibrary() 266 | { 267 | if (string.IsNullOrWhiteSpace(this.libraryFilePath)) 268 | { 269 | string currentArchitecture = IntPtr.Size == 4 ? "x86" : "x64"; // magic check 270 | 271 | if (File.Exists(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "7z-" + currentArchitecture + ".dll"))) 272 | { 273 | this.libraryFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "7z-" + currentArchitecture + ".dll"); 274 | } 275 | else if (File.Exists(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin", "7z-" + currentArchitecture + ".dll"))) 276 | { 277 | this.libraryFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin", "7z-" + currentArchitecture + ".dll"); 278 | } 279 | else if (File.Exists(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin", currentArchitecture, "7z.dll"))) 280 | { 281 | this.libraryFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin", currentArchitecture, "7z.dll"); 282 | } 283 | else if (File.Exists(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, currentArchitecture, "7z.dll"))) 284 | { 285 | this.libraryFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, currentArchitecture, "7z.dll"); 286 | } 287 | else if (File.Exists(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "7-Zip", "7z.dll"))) 288 | { 289 | this.libraryFilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "7-Zip", "7z.dll"); 290 | } 291 | } 292 | 293 | if (string.IsNullOrWhiteSpace(this.libraryFilePath)) 294 | { 295 | throw new SevenZipException("libraryFilePath not set"); 296 | } 297 | 298 | if (!File.Exists(this.libraryFilePath)) 299 | { 300 | throw new SevenZipException("7z.dll not found"); 301 | } 302 | 303 | try 304 | { 305 | this.sevenZipHandle = new SevenZipHandle(this.libraryFilePath); 306 | } 307 | catch (Exception e) 308 | { 309 | throw new SevenZipException("Unable to initialize SevenZipHandle", e); 310 | } 311 | } 312 | 313 | private bool GuessFormatFromExtension(string fileExtension, out SevenZipFormat format) 314 | { 315 | if (string.IsNullOrWhiteSpace(fileExtension)) 316 | { 317 | format = SevenZipFormat.Undefined; 318 | return false; 319 | } 320 | 321 | fileExtension = fileExtension.TrimStart('.').Trim().ToLowerInvariant(); 322 | 323 | if (fileExtension.Equals("rar")) 324 | { 325 | // 7z has different GUID for Pre-RAR5 and RAR5, but they have both same extension (.rar) 326 | // If it is [0x52 0x61 0x72 0x21 0x1A 0x07 0x01 0x00] then file is RAR5 otherwise RAR. 327 | // https://www.rarlab.com/technote.htm 328 | 329 | // We are unable to guess right format just by looking at extension and have to check signature 330 | 331 | format = SevenZipFormat.Undefined; 332 | return false; 333 | } 334 | 335 | if (!Formats.ExtensionFormatMapping.ContainsKey(fileExtension)) 336 | { 337 | format = SevenZipFormat.Undefined; 338 | return false; 339 | } 340 | 341 | format = Formats.ExtensionFormatMapping[fileExtension]; 342 | return true; 343 | } 344 | 345 | 346 | private bool GuessFormatFromSignature(string filePath, out SevenZipFormat format) 347 | { 348 | using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) 349 | { 350 | return GuessFormatFromSignature(fileStream, out format); 351 | } 352 | } 353 | 354 | private bool GuessFormatFromSignature(Stream stream, out SevenZipFormat format) 355 | { 356 | int longestSignature = Formats.FileSignatures.Values.OrderByDescending(v => v.Length).First().Length; 357 | 358 | byte[] archiveFileSignature = new byte[longestSignature]; 359 | int bytesRead = stream.Read(archiveFileSignature, 0, longestSignature); 360 | 361 | stream.Position -= bytesRead; // go back o beginning 362 | 363 | if (bytesRead != longestSignature) 364 | { 365 | format = SevenZipFormat.Undefined; 366 | return false; 367 | } 368 | 369 | foreach (KeyValuePair pair in Formats.FileSignatures) 370 | { 371 | if (archiveFileSignature.Take(pair.Value.Length).SequenceEqual(pair.Value)) 372 | { 373 | format = pair.Key; 374 | return true; 375 | } 376 | } 377 | 378 | format = SevenZipFormat.Undefined; 379 | return false; 380 | } 381 | 382 | ~ArchiveFile() 383 | { 384 | this.Dispose(false); 385 | } 386 | 387 | protected void Dispose(bool disposing) 388 | { 389 | if (this.archiveStream != null) 390 | { 391 | this.archiveStream.Dispose(); 392 | } 393 | 394 | if (this.archive != null) 395 | { 396 | Marshal.ReleaseComObject(this.archive); 397 | } 398 | 399 | if (this.sevenZipHandle != null) 400 | { 401 | this.sevenZipHandle.Dispose(); 402 | } 403 | } 404 | 405 | public void Dispose() 406 | { 407 | this.Dispose(true); 408 | GC.SuppressFinalize(this); 409 | } 410 | } 411 | } 412 | -------------------------------------------------------------------------------- /SevenZipExtractor/ArchiveFileCallback.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace SevenZipExtractor 5 | { 6 | internal class ArchiveFileCallback : IArchiveExtractCallback 7 | { 8 | private readonly string fileName; 9 | private readonly uint fileNumber; 10 | private OutStreamWrapper fileStream; // to be removed 11 | 12 | public ArchiveFileCallback(uint fileNumber, string fileName) 13 | { 14 | this.fileNumber = fileNumber; 15 | this.fileName = fileName; 16 | } 17 | 18 | public void SetTotal(ulong total) 19 | { 20 | } 21 | 22 | public void SetCompleted(ref ulong completeValue) 23 | { 24 | } 25 | 26 | public int GetStream(uint index, out ISequentialOutStream outStream, AskMode askExtractMode) 27 | { 28 | if ((index != this.fileNumber) || (askExtractMode != AskMode.kExtract)) 29 | { 30 | outStream = null; 31 | return 0; 32 | } 33 | 34 | string fileDir = Path.GetDirectoryName(this.fileName); 35 | 36 | if (!string.IsNullOrEmpty(fileDir)) 37 | { 38 | Directory.CreateDirectory(fileDir); 39 | } 40 | 41 | this.fileStream = new OutStreamWrapper(File.Create(this.fileName)); 42 | 43 | outStream = this.fileStream; 44 | 45 | return 0; 46 | } 47 | 48 | public void PrepareOperation(AskMode askExtractMode) 49 | { 50 | } 51 | 52 | public void SetOperationResult(OperationResult resultEOperationResult) 53 | { 54 | this.fileStream.Dispose(); 55 | } 56 | } 57 | } -------------------------------------------------------------------------------- /SevenZipExtractor/ArchiveStreamCallback.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | 3 | namespace SevenZipExtractor 4 | { 5 | internal class ArchiveStreamCallback : IArchiveExtractCallback, ICryptoGetTextPassword 6 | { 7 | private readonly uint fileNumber; 8 | private readonly Stream stream; 9 | 10 | public string Password { get; } 11 | 12 | public ArchiveStreamCallback(uint fileNumber, Stream stream, string password = null) 13 | { 14 | this.fileNumber = fileNumber; 15 | this.stream = stream; 16 | Password = password ?? ""; 17 | } 18 | 19 | public void SetTotal(ulong total) 20 | { 21 | } 22 | 23 | public void SetCompleted(ref ulong completeValue) 24 | { 25 | } 26 | 27 | public int CryptoGetTextPassword(out string password) 28 | { 29 | password = this.Password; 30 | return 0; 31 | } 32 | 33 | public int GetStream(uint index, out ISequentialOutStream outStream, AskMode askExtractMode) 34 | { 35 | if ((index != this.fileNumber) || (askExtractMode != AskMode.kExtract)) 36 | { 37 | outStream = null; 38 | return 0; 39 | } 40 | 41 | outStream = new OutStreamWrapper(this.stream); 42 | 43 | return 0; 44 | } 45 | 46 | public void PrepareOperation(AskMode askExtractMode) 47 | { 48 | } 49 | 50 | public void SetOperationResult(OperationResult resultEOperationResult) 51 | { 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /SevenZipExtractor/ArchiveStreamsCallback.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | 4 | namespace SevenZipExtractor 5 | { 6 | internal class ArchiveStreamsCallback : IArchiveExtractCallback, ICryptoGetTextPassword 7 | { 8 | private readonly IList streams; 9 | 10 | public string Password { get; } 11 | 12 | public ArchiveStreamsCallback(IList streams, string password = null) 13 | { 14 | this.streams = streams; 15 | Password = password; 16 | } 17 | public int CryptoGetTextPassword(out string password) 18 | { 19 | password = Password; 20 | return 0; 21 | } 22 | 23 | public void SetTotal(ulong total) 24 | { 25 | } 26 | 27 | public void SetCompleted(ref ulong completeValue) 28 | { 29 | } 30 | 31 | public int GetStream(uint index, out ISequentialOutStream outStream, AskMode askExtractMode) 32 | { 33 | if (askExtractMode != AskMode.kExtract) 34 | { 35 | outStream = null; 36 | return 0; 37 | } 38 | 39 | if (this.streams == null) 40 | { 41 | outStream = null; 42 | return 0; 43 | } 44 | 45 | Stream stream = this.streams[(int) index]; 46 | 47 | if (stream == null) 48 | { 49 | outStream = null; 50 | return 0; 51 | } 52 | 53 | outStream = new OutStreamWrapper(stream); 54 | 55 | return 0; 56 | } 57 | 58 | public void PrepareOperation(AskMode askExtractMode) 59 | { 60 | } 61 | 62 | public void SetOperationResult(OperationResult resultEOperationResult) 63 | { 64 | } 65 | } 66 | } -------------------------------------------------------------------------------- /SevenZipExtractor/Entry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace SevenZipExtractor 5 | { 6 | public class Entry 7 | { 8 | private readonly IInArchive archive; 9 | private readonly uint index; 10 | 11 | internal Entry(IInArchive archive, uint index) 12 | { 13 | this.archive = archive; 14 | this.index = index; 15 | } 16 | 17 | /// 18 | /// Name of the file with its relative path within the archive 19 | /// 20 | public string FileName { get; internal set; } 21 | /// 22 | /// True if entry is a folder, false if it is a file 23 | /// 24 | public bool IsFolder { get; internal set; } 25 | /// 26 | /// Original entry size 27 | /// 28 | public ulong Size { get; internal set; } 29 | /// 30 | /// Entry size in a archived state 31 | /// 32 | public ulong PackedSize { get; internal set; } 33 | 34 | /// 35 | /// Date and time of the file (entry) creation 36 | /// 37 | public DateTime CreationTime { get; internal set; } 38 | 39 | /// 40 | /// Date and time of the last change of the file (entry) 41 | /// 42 | public DateTime LastWriteTime { get; internal set; } 43 | 44 | /// 45 | /// Date and time of the last access of the file (entry) 46 | /// 47 | public DateTime LastAccessTime { get; internal set; } 48 | 49 | /// 50 | /// CRC hash of the entry 51 | /// 52 | public UInt32 CRC { get; internal set; } 53 | 54 | /// 55 | /// Attributes of the entry 56 | /// 57 | public UInt32 Attributes { get; internal set; } 58 | 59 | /// 60 | /// True if entry is encrypted, otherwise false 61 | /// 62 | public bool IsEncrypted { get; internal set; } 63 | 64 | /// 65 | /// Comment of the entry 66 | /// 67 | public string Comment { get; internal set; } 68 | 69 | /// 70 | /// Compression method of the entry 71 | /// 72 | public string Method { get; internal set; } 73 | 74 | /// 75 | /// Host operating system of the entry 76 | /// 77 | public string HostOS { get; internal set; } 78 | 79 | /// 80 | /// True if there are parts of this file in previous split archive parts 81 | /// 82 | public bool IsSplitBefore { get; set; } 83 | 84 | /// 85 | /// True if there are parts of this file in next split archive parts 86 | /// 87 | public bool IsSplitAfter { get; set; } 88 | 89 | public void Extract(string fileName, bool preserveTimestamp = true) 90 | { 91 | if (this.IsFolder) 92 | { 93 | Directory.CreateDirectory(fileName); 94 | return; 95 | } 96 | 97 | string directoryName = Path.GetDirectoryName(fileName); 98 | 99 | if (!string.IsNullOrWhiteSpace(directoryName)) 100 | { 101 | Directory.CreateDirectory(directoryName); 102 | } 103 | 104 | using (FileStream fileStream = File.Create(fileName)) 105 | { 106 | this.Extract(fileStream); 107 | } 108 | 109 | if (preserveTimestamp) 110 | { 111 | File.SetLastWriteTime(fileName, this.LastWriteTime); 112 | } 113 | } 114 | public void Extract(Stream stream, string password = null) 115 | { 116 | this.archive.Extract(new[] { this.index }, 1, 0, new ArchiveStreamCallback(this.index, stream, password)); 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /SevenZipExtractor/Formats.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace SevenZipExtractor 5 | { 6 | public class Formats 7 | { 8 | internal static readonly Dictionary ExtensionFormatMapping = new Dictionary 9 | { 10 | {"7z", SevenZipFormat.SevenZip}, 11 | {"gz", SevenZipFormat.GZip}, 12 | {"tar", SevenZipFormat.Tar}, 13 | {"rar", SevenZipFormat.Rar}, 14 | {"zip", SevenZipFormat.Zip}, 15 | {"lzma", SevenZipFormat.Lzma}, 16 | {"lzh", SevenZipFormat.Lzh}, 17 | {"arj", SevenZipFormat.Arj}, 18 | {"bz2", SevenZipFormat.BZip2}, 19 | {"cab", SevenZipFormat.Cab}, 20 | {"chm", SevenZipFormat.Chm}, 21 | {"deb", SevenZipFormat.Deb}, 22 | {"iso", SevenZipFormat.Iso}, 23 | {"rpm", SevenZipFormat.Rpm}, 24 | {"wim", SevenZipFormat.Wim}, 25 | {"udf", SevenZipFormat.Udf}, 26 | {"mub", SevenZipFormat.Mub}, 27 | {"xar", SevenZipFormat.Xar}, 28 | {"hfs", SevenZipFormat.Hfs}, 29 | {"dmg", SevenZipFormat.Dmg}, 30 | {"z", SevenZipFormat.Lzw}, 31 | {"xz", SevenZipFormat.XZ}, 32 | {"flv", SevenZipFormat.Flv}, 33 | {"swf", SevenZipFormat.Swf}, 34 | {"exe", SevenZipFormat.PE}, 35 | {"dll", SevenZipFormat.PE}, 36 | {"vhd", SevenZipFormat.Vhd} 37 | }; 38 | 39 | internal static Dictionary FormatGuidMapping = new Dictionary 40 | { 41 | {SevenZipFormat.SevenZip, new Guid("23170f69-40c1-278a-1000-000110070000")}, 42 | {SevenZipFormat.Arj, new Guid("23170f69-40c1-278a-1000-000110040000")}, 43 | {SevenZipFormat.BZip2, new Guid("23170f69-40c1-278a-1000-000110020000")}, 44 | {SevenZipFormat.Cab, new Guid("23170f69-40c1-278a-1000-000110080000")}, 45 | {SevenZipFormat.Chm, new Guid("23170f69-40c1-278a-1000-000110e90000")}, 46 | {SevenZipFormat.Compound, new Guid("23170f69-40c1-278a-1000-000110e50000")}, 47 | {SevenZipFormat.Cpio, new Guid("23170f69-40c1-278a-1000-000110ed0000")}, 48 | {SevenZipFormat.Deb, new Guid("23170f69-40c1-278a-1000-000110ec0000")}, 49 | {SevenZipFormat.GZip, new Guid("23170f69-40c1-278a-1000-000110ef0000")}, 50 | {SevenZipFormat.Iso, new Guid("23170f69-40c1-278a-1000-000110e70000")}, 51 | {SevenZipFormat.Lzh, new Guid("23170f69-40c1-278a-1000-000110060000")}, 52 | {SevenZipFormat.Lzma, new Guid("23170f69-40c1-278a-1000-0001100a0000")}, 53 | {SevenZipFormat.Nsis, new Guid("23170f69-40c1-278a-1000-000110090000")}, 54 | {SevenZipFormat.Rar, new Guid("23170f69-40c1-278a-1000-000110030000")}, 55 | {SevenZipFormat.Rar5, new Guid("23170f69-40c1-278a-1000-000110CC0000")}, 56 | {SevenZipFormat.Rpm, new Guid("23170f69-40c1-278a-1000-000110eb0000")}, 57 | {SevenZipFormat.Split, new Guid("23170f69-40c1-278a-1000-000110ea0000")}, 58 | {SevenZipFormat.Tar, new Guid("23170f69-40c1-278a-1000-000110ee0000")}, 59 | {SevenZipFormat.Wim, new Guid("23170f69-40c1-278a-1000-000110e60000")}, 60 | {SevenZipFormat.Lzw, new Guid("23170f69-40c1-278a-1000-000110050000")}, 61 | {SevenZipFormat.Zip, new Guid("23170f69-40c1-278a-1000-000110010000")}, 62 | {SevenZipFormat.Udf, new Guid("23170f69-40c1-278a-1000-000110E00000")}, 63 | {SevenZipFormat.Xar, new Guid("23170f69-40c1-278a-1000-000110E10000")}, 64 | {SevenZipFormat.Mub, new Guid("23170f69-40c1-278a-1000-000110E20000")}, 65 | {SevenZipFormat.Hfs, new Guid("23170f69-40c1-278a-1000-000110E30000")}, 66 | {SevenZipFormat.Dmg, new Guid("23170f69-40c1-278a-1000-000110E40000")}, 67 | {SevenZipFormat.XZ, new Guid("23170f69-40c1-278a-1000-0001100C0000")}, 68 | {SevenZipFormat.Mslz, new Guid("23170f69-40c1-278a-1000-000110D50000")}, 69 | {SevenZipFormat.PE, new Guid("23170f69-40c1-278a-1000-000110DD0000")}, 70 | {SevenZipFormat.Elf, new Guid("23170f69-40c1-278a-1000-000110DE0000")}, 71 | {SevenZipFormat.Swf, new Guid("23170f69-40c1-278a-1000-000110D70000")}, 72 | {SevenZipFormat.Vhd, new Guid("23170f69-40c1-278a-1000-000110DC0000")}, 73 | {SevenZipFormat.Flv, new Guid("23170f69-40c1-278a-1000-000110D60000")}, 74 | {SevenZipFormat.SquashFS, new Guid("23170f69-40c1-278a-1000-000110D20000")}, 75 | {SevenZipFormat.Lzma86, new Guid("23170f69-40c1-278a-1000-0001100B0000")}, 76 | {SevenZipFormat.Ppmd, new Guid("23170f69-40c1-278a-1000-0001100D0000")}, 77 | {SevenZipFormat.TE, new Guid("23170f69-40c1-278a-1000-000110CF0000")}, 78 | {SevenZipFormat.UEFIc, new Guid("23170f69-40c1-278a-1000-000110D00000")}, 79 | {SevenZipFormat.UEFIs, new Guid("23170f69-40c1-278a-1000-000110D10000")}, 80 | {SevenZipFormat.CramFS, new Guid("23170f69-40c1-278a-1000-000110D30000")}, 81 | {SevenZipFormat.APM, new Guid("23170f69-40c1-278a-1000-000110D40000")}, 82 | {SevenZipFormat.Swfc, new Guid("23170f69-40c1-278a-1000-000110D80000")}, 83 | {SevenZipFormat.Ntfs, new Guid("23170f69-40c1-278a-1000-000110D90000")}, 84 | {SevenZipFormat.Fat, new Guid("23170f69-40c1-278a-1000-000110DA0000")}, 85 | {SevenZipFormat.Mbr, new Guid("23170f69-40c1-278a-1000-000110DB0000")}, 86 | {SevenZipFormat.MachO, new Guid("23170f69-40c1-278a-1000-000110DF0000")} 87 | }; 88 | 89 | internal static Dictionary FileSignatures = new Dictionary 90 | { 91 | {SevenZipFormat.Rar5, new byte[] {0x52, 0x61, 0x72, 0x21, 0x1A, 0x07, 0x01, 0x00}}, 92 | {SevenZipFormat.Rar, new byte[] { 0x52, 0x61, 0x72, 0x21, 0x1A, 0x07, 0x00 }}, 93 | {SevenZipFormat.Vhd, new byte[] { 0x63, 0x6F, 0x6E, 0x65, 0x63, 0x74, 0x69, 0x78 }}, 94 | {SevenZipFormat.Deb, new byte[] { 0x21, 0x3C, 0x61, 0x72, 0x63, 0x68, 0x3E }}, 95 | {SevenZipFormat.Dmg, new byte[] { 0x78, 0x01, 0x73, 0x0D, 0x62, 0x62, 0x60 }}, 96 | {SevenZipFormat.SevenZip, new byte[] { 0x37, 0x7A, 0xBC, 0xAF, 0x27, 0x1C }}, 97 | {SevenZipFormat.Tar, new byte[] { 0x75, 0x73, 0x74, 0x61, 0x72 }}, 98 | {SevenZipFormat.Iso, new byte[] { 0x43, 0x44, 0x30, 0x30, 0x31 }}, 99 | {SevenZipFormat.Cab, new byte[] { 0x4D, 0x53, 0x43, 0x46 }}, 100 | {SevenZipFormat.Rpm, new byte[] { 0xed, 0xab, 0xee, 0xdb }}, 101 | {SevenZipFormat.Xar, new byte[] { 0x78, 0x61, 0x72, 0x21 }}, 102 | {SevenZipFormat.Chm, new byte[] { 0x49, 0x54, 0x53, 0x46 }}, 103 | {SevenZipFormat.BZip2, new byte[] { 0x42, 0x5A, 0x68 }}, 104 | {SevenZipFormat.Flv, new byte[] { 0x46, 0x4C, 0x56 }}, 105 | {SevenZipFormat.Swf, new byte[] { 0x46, 0x57, 0x53 }}, 106 | {SevenZipFormat.GZip, new byte[] { 0x1f, 0x0b }}, 107 | {SevenZipFormat.Zip, new byte[] { 0x50, 0x4b }}, 108 | {SevenZipFormat.Arj, new byte[] { 0x60, 0xEA }}, 109 | {SevenZipFormat.Lzh, new byte[] { 0x2D, 0x6C, 0x68 }}, 110 | {SevenZipFormat.SquashFS, new byte[] {0x68, 0x73, 0x71, 0x73}} 111 | }; 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /SevenZipExtractor/IArchiveExtractCallback.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | 3 | namespace SevenZipExtractor 4 | { 5 | [ComImport] 6 | [Guid("23170F69-40C1-278A-0000-000600200000")] 7 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 8 | internal interface IArchiveExtractCallback //: IProgress 9 | { 10 | void SetTotal(ulong total); 11 | void SetCompleted([In] ref ulong completeValue); 12 | 13 | [PreserveSig] 14 | int GetStream( 15 | uint index, 16 | [MarshalAs(UnmanagedType.Interface)] out ISequentialOutStream outStream, 17 | AskMode askExtractMode); 18 | // GetStream OUT: S_OK - OK, S_FALSE - skeep this file 19 | 20 | void PrepareOperation(AskMode askExtractMode); 21 | void SetOperationResult(OperationResult resultEOperationResult); 22 | } 23 | } -------------------------------------------------------------------------------- /SevenZipExtractor/Kernel32Dll.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | using System.Security; 4 | 5 | namespace SevenZipExtractor 6 | { 7 | internal static class Kernel32Dll 8 | { 9 | [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 10 | internal static extern SafeLibraryHandle LoadLibrary([MarshalAs(UnmanagedType.LPTStr)] string lpFileName); 11 | 12 | [DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)] 13 | internal static extern IntPtr GetProcAddress(SafeLibraryHandle hModule, [MarshalAs(UnmanagedType.LPStr)] string procName); 14 | 15 | [SuppressUnmanagedCodeSecurity] 16 | [DllImport("kernel32.dll")] 17 | [return: MarshalAs(UnmanagedType.Bool)] 18 | internal static extern bool FreeLibrary(IntPtr hModule); 19 | } 20 | } -------------------------------------------------------------------------------- /SevenZipExtractor/SafeLibraryHandle.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.ConstrainedExecution; 3 | using Microsoft.Win32.SafeHandles; 4 | 5 | namespace SevenZipExtractor 6 | { 7 | internal sealed class SafeLibraryHandle : SafeHandleZeroOrMinusOneIsInvalid 8 | { 9 | public SafeLibraryHandle() : base(true) 10 | { 11 | } 12 | 13 | /// Release library handle 14 | /// true if the handle was released 15 | [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] 16 | protected override bool ReleaseHandle() 17 | { 18 | return Kernel32Dll.FreeLibrary(this.handle); 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /SevenZipExtractor/SevenZipException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | 4 | namespace SevenZipExtractor 5 | { 6 | public class SevenZipException : Exception 7 | { 8 | public SevenZipException() 9 | { 10 | } 11 | 12 | public SevenZipException(string message) : base(message) 13 | { 14 | } 15 | 16 | public SevenZipException(string message, Exception innerException) : base(message, innerException) 17 | { 18 | } 19 | 20 | protected SevenZipException(SerializationInfo info, StreamingContext context) : base(info, context) 21 | { 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /SevenZipExtractor/SevenZipExtractor.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | net45;netstandard2.0 4 | SevenZipWrapper 5 | SevenZipWrapper 6 | C# wrapper for 7z.dll (included) 7 | Copyright 2025 8 | 1.0.19 9 | bin\$(Configuration)\ 10 | Eugene Sichkar, Alexander Selishchev, @matortheeternal, Hajin Jang, Artem Tarasov, Jose Pineiro, Raphael Stoeckli, Wojciech Nagórski 11 | SevenZipExtractor 12 | https://github.com/adoconnection/SevenZipExtractor 13 | 7Zip APM Arj BZip2 Cab Chm Compound Cpio CramFS Deb Dll Dmg Exe Fat Flv GZip Hfs Iso Lzh Lzma Lzma86 Mach-O Mbr Mub Nsis Ntfs Ppmd Rar Rar5 Rpm Split SquashFS Swf Swfc Tar TE Udf UEFIc UEFIs Vhd Wim Xar XZ Z Zip 14 | 1.0.19 15 | 16 | 17 | 18 | 19 | build\x64\ 20 | PreserveNewest 21 | 22 | true 23 | 24 | 25 | build\x86\ 26 | PreserveNewest 27 | true 28 | 29 | 30 | 31 | Never 32 | 33 | 34 | -------------------------------------------------------------------------------- /SevenZipExtractor/SevenZipExtractor.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 10 | 11 | %(RecursiveDir)%(FileName)%(Extension) 12 | PreserveNewest 13 | 14 | 15 | -------------------------------------------------------------------------------- /SevenZipExtractor/SevenZipFormat.cs: -------------------------------------------------------------------------------- 1 | namespace SevenZipExtractor 2 | { 3 | /// 4 | /// 5 | /// 6 | public enum SevenZipFormat 7 | { 8 | // Default invalid format value 9 | Undefined = 0, 10 | 11 | /// 12 | /// Open 7-zip archive format. 13 | /// 14 | /// Wikipedia information 15 | SevenZip, 16 | 17 | /// 18 | /// Proprietary Arj archive format. 19 | /// 20 | /// Wikipedia information 21 | Arj, 22 | 23 | /// 24 | /// Open Bzip2 archive format. 25 | /// 26 | /// Wikipedia information 27 | BZip2, 28 | 29 | /// 30 | /// Microsoft cabinet archive format. 31 | /// 32 | /// Wikipedia information 33 | Cab, 34 | 35 | /// 36 | /// Microsoft Compiled HTML Help file format. 37 | /// 38 | /// Wikipedia information 39 | Chm, 40 | 41 | /// 42 | /// Microsoft Compound file format. 43 | /// 44 | /// Wikipedia information 45 | Compound, 46 | 47 | /// 48 | /// Open Cpio archive format. 49 | /// 50 | /// Wikipedia information 51 | Cpio, 52 | 53 | /// 54 | /// Open Debian software package format. 55 | /// 56 | /// Wikipedia information 57 | Deb, 58 | 59 | /// 60 | /// Open Gzip archive format. 61 | /// 62 | /// Wikipedia information 63 | GZip, 64 | 65 | /// 66 | /// Open ISO disk image format. 67 | /// 68 | /// Wikipedia information 69 | Iso, 70 | 71 | /// 72 | /// Open Lzh archive format. 73 | /// 74 | /// Wikipedia information 75 | Lzh, 76 | 77 | /// 78 | /// Open core 7-zip Lzma raw archive format. 79 | /// 80 | /// Wikipedia information 81 | Lzma, 82 | 83 | /// 84 | /// Nullsoft installation package format. 85 | /// 86 | /// Wikipedia information 87 | Nsis, 88 | 89 | /// 90 | /// RarLab Rar archive format. 91 | /// 92 | /// Wikipedia information 93 | Rar, 94 | 95 | /// 96 | /// RarLab Rar archive format, version 5. 97 | /// 98 | /// Wikipedia information 99 | Rar5, 100 | 101 | /// 102 | /// Open Rpm software package format. 103 | /// 104 | /// Wikipedia information 105 | Rpm, 106 | 107 | /// 108 | /// Open split file format. 109 | /// 110 | /// Wikipedia information 111 | Split, 112 | 113 | /// 114 | /// Open Tar archive format. 115 | /// 116 | /// Wikipedia information 117 | Tar, 118 | 119 | /// 120 | /// Microsoft Windows Imaging disk image format. 121 | /// 122 | /// Wikipedia information 123 | Wim, 124 | 125 | /// 126 | /// Open LZW archive format; implemented in "compress" program; also known as "Z" archive format. 127 | /// 128 | /// Wikipedia information 129 | Lzw, 130 | 131 | /// 132 | /// Open Zip archive format. 133 | /// 134 | /// Wikipedia information 135 | Zip, 136 | 137 | /// 138 | /// Open Udf disk image format. 139 | /// 140 | Udf, 141 | 142 | /// 143 | /// Xar open source archive format. 144 | /// 145 | /// Wikipedia information 146 | Xar, 147 | 148 | /// 149 | /// Mub 150 | /// 151 | Mub, 152 | 153 | /// 154 | /// Macintosh Disk Image on CD. 155 | /// 156 | /// Wikipedia information 157 | Hfs, 158 | 159 | /// 160 | /// Apple Mac OS X Disk Copy Disk Image format. 161 | /// 162 | Dmg, 163 | 164 | /// 165 | /// Open Xz archive format. 166 | /// 167 | /// Wikipedia information 168 | XZ, 169 | 170 | /// 171 | /// MSLZ archive format. 172 | /// 173 | Mslz, 174 | 175 | /// 176 | /// Flash video format. 177 | /// 178 | /// Wikipedia information 179 | Flv, 180 | 181 | /// 182 | /// Shockwave Flash format. 183 | /// 184 | /// Wikipedia information 185 | Swf, 186 | 187 | /// 188 | /// Windows PE executable format. 189 | /// 190 | /// Wikipedia information 191 | PE, 192 | 193 | /// 194 | /// Linux executable Elf format. 195 | /// 196 | /// Wikipedia information 197 | Elf, 198 | 199 | /// 200 | /// Windows Installer Database. 201 | /// 202 | /// Wikipedia information 203 | Msi, 204 | 205 | /// 206 | /// Microsoft virtual hard disk file format. 207 | /// 208 | /// Wikipedia information 209 | Vhd, 210 | 211 | /// 212 | /// SquashFS file system format. 213 | /// 214 | /// Wikipedia information 215 | SquashFS, 216 | 217 | /// 218 | /// Lzma86 file format. 219 | /// 220 | Lzma86, 221 | 222 | /// 223 | /// Prediction by Partial Matching by Dmitry algorithm. 224 | /// 225 | /// Wikipedia information 226 | Ppmd, 227 | 228 | /// 229 | /// TE format. 230 | /// 231 | TE, 232 | 233 | /// 234 | /// UEFIc format. 235 | /// 236 | /// Wikipedia information 237 | UEFIc, 238 | 239 | /// 240 | /// UEFIs format. 241 | /// 242 | /// Wikipedia information 243 | UEFIs, 244 | 245 | /// 246 | /// Compressed ROM file system format. 247 | /// 248 | /// Wikipedia information 249 | CramFS, 250 | 251 | /// 252 | /// APM format. 253 | /// 254 | APM, 255 | 256 | /// 257 | /// Swfc format. 258 | /// 259 | Swfc, 260 | 261 | /// 262 | /// NTFS file system format. 263 | /// 264 | /// Wikipedia information 265 | Ntfs, 266 | 267 | /// 268 | /// FAT file system format. 269 | /// 270 | /// Wikipedia information 271 | Fat, 272 | 273 | /// 274 | /// MBR format. 275 | /// 276 | /// Wikipedia information 277 | Mbr, 278 | 279 | /// 280 | /// Mach-O file format. 281 | /// 282 | /// Wikipedia information 283 | MachO 284 | } 285 | } -------------------------------------------------------------------------------- /SevenZipExtractor/SevenZipHandle.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using System.Runtime.InteropServices; 4 | 5 | namespace SevenZipExtractor 6 | { 7 | internal class SevenZipHandle : IDisposable 8 | { 9 | private SafeLibraryHandle sevenZipSafeHandle; 10 | 11 | public SevenZipHandle(string sevenZipLibPath) 12 | { 13 | this.sevenZipSafeHandle = Kernel32Dll.LoadLibrary(sevenZipLibPath); 14 | 15 | if (this.sevenZipSafeHandle.IsInvalid) 16 | { 17 | throw new Win32Exception(); 18 | } 19 | 20 | IntPtr functionPtr = Kernel32Dll.GetProcAddress(this.sevenZipSafeHandle, "GetHandlerProperty"); 21 | 22 | // Not valid dll 23 | if (functionPtr == IntPtr.Zero) 24 | { 25 | this.sevenZipSafeHandle.Close(); 26 | throw new ArgumentException(); 27 | } 28 | } 29 | 30 | ~SevenZipHandle() 31 | { 32 | this.Dispose(false); 33 | } 34 | 35 | protected void Dispose(bool disposing) 36 | { 37 | if ((this.sevenZipSafeHandle != null) && !this.sevenZipSafeHandle.IsClosed) 38 | { 39 | this.sevenZipSafeHandle.Close(); 40 | } 41 | 42 | this.sevenZipSafeHandle = null; 43 | } 44 | 45 | public void Dispose() 46 | { 47 | this.Dispose(true); 48 | GC.SuppressFinalize(this); 49 | } 50 | 51 | public IInArchive CreateInArchive(Guid classId) 52 | { 53 | if (this.sevenZipSafeHandle == null) 54 | { 55 | throw new ObjectDisposedException("SevenZipHandle"); 56 | } 57 | 58 | IntPtr procAddress = Kernel32Dll.GetProcAddress(this.sevenZipSafeHandle, "CreateObject"); 59 | CreateObjectDelegate createObject = (CreateObjectDelegate) Marshal.GetDelegateForFunctionPointer(procAddress, typeof (CreateObjectDelegate)); 60 | 61 | object result; 62 | Guid interfaceId = typeof (IInArchive).GUID; 63 | createObject(ref classId, ref interfaceId, out result); 64 | 65 | return result as IInArchive; 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /SevenZipExtractor/SevenZipInterface.cs: -------------------------------------------------------------------------------- 1 | // Version 1.5 2 | 3 | using System; 4 | using System.Globalization; 5 | using System.IO; 6 | using System.Runtime.InteropServices; 7 | using System.Security.Permissions; 8 | using System.Threading; 9 | 10 | namespace SevenZipExtractor 11 | { 12 | [StructLayout(LayoutKind.Sequential)] 13 | internal struct PropArray 14 | { 15 | uint length; 16 | IntPtr pointerValues; 17 | } 18 | 19 | [StructLayout(LayoutKind.Explicit)] 20 | internal struct PropVariant 21 | { 22 | [DllImport("ole32.dll")] 23 | private static extern int PropVariantClear(ref PropVariant pvar); 24 | 25 | [FieldOffset(0)] public ushort vt; 26 | [FieldOffset(8)] public IntPtr pointerValue; 27 | [FieldOffset(8)] public byte byteValue; 28 | [FieldOffset(8)] public long longValue; 29 | [FieldOffset(8)] public System.Runtime.InteropServices.ComTypes.FILETIME filetime; 30 | [FieldOffset(8)] public PropArray propArray; 31 | 32 | public VarEnum VarType 33 | { 34 | get 35 | { 36 | return (VarEnum) this.vt; 37 | } 38 | } 39 | 40 | public void Clear() 41 | { 42 | switch (this.VarType) 43 | { 44 | case VarEnum.VT_EMPTY: 45 | break; 46 | 47 | case VarEnum.VT_NULL: 48 | case VarEnum.VT_I2: 49 | case VarEnum.VT_I4: 50 | case VarEnum.VT_R4: 51 | case VarEnum.VT_R8: 52 | case VarEnum.VT_CY: 53 | case VarEnum.VT_DATE: 54 | case VarEnum.VT_ERROR: 55 | case VarEnum.VT_BOOL: 56 | //case VarEnum.VT_DECIMAL: 57 | case VarEnum.VT_I1: 58 | case VarEnum.VT_UI1: 59 | case VarEnum.VT_UI2: 60 | case VarEnum.VT_UI4: 61 | case VarEnum.VT_I8: 62 | case VarEnum.VT_UI8: 63 | case VarEnum.VT_INT: 64 | case VarEnum.VT_UINT: 65 | case VarEnum.VT_HRESULT: 66 | case VarEnum.VT_FILETIME: 67 | this.vt = 0; 68 | break; 69 | 70 | default: 71 | PropVariantClear(ref this); 72 | break; 73 | } 74 | } 75 | 76 | public object GetObject() 77 | { 78 | switch (this.VarType) 79 | { 80 | case VarEnum.VT_EMPTY: 81 | return null; 82 | 83 | case VarEnum.VT_FILETIME: 84 | return DateTime.FromFileTime(this.longValue); 85 | 86 | default: 87 | GCHandle PropHandle = GCHandle.Alloc(this, GCHandleType.Pinned); 88 | 89 | try 90 | { 91 | return Marshal.GetObjectForNativeVariant(PropHandle.AddrOfPinnedObject()); 92 | } 93 | finally 94 | { 95 | PropHandle.Free(); 96 | } 97 | } 98 | } 99 | } 100 | 101 | [ComImport] 102 | [Guid("23170F69-40C1-278A-0000-000000050000")] 103 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 104 | internal interface IProgress 105 | { 106 | void SetTotal(ulong total); 107 | void SetCompleted([In] ref ulong completeValue); 108 | } 109 | 110 | [ComImport] 111 | [Guid("23170F69-40C1-278A-0000-000600100000")] 112 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 113 | internal interface IArchiveOpenCallback 114 | { 115 | // ref ulong replaced with IntPtr because handlers ofter pass null value 116 | // read actual value with Marshal.ReadInt64 117 | void SetTotal( 118 | IntPtr files, // [In] ref ulong files, can use 'ulong* files' but it is unsafe 119 | IntPtr bytes); // [In] ref ulong bytes 120 | 121 | void SetCompleted( 122 | IntPtr files, // [In] ref ulong files 123 | IntPtr bytes); // [In] ref ulong bytes 124 | } 125 | 126 | [ComImport] 127 | [Guid("23170F69-40C1-278A-0000-000500100000")] 128 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 129 | internal interface ICryptoGetTextPassword 130 | { 131 | [PreserveSig] 132 | int CryptoGetTextPassword( 133 | [MarshalAs(UnmanagedType.BStr)] out string password); 134 | 135 | //[return : MarshalAs(UnmanagedType.BStr)] 136 | //string CryptoGetTextPassword(); 137 | } 138 | 139 | [ComImport] 140 | [Guid("23170F69-40C1-278A-0000-000500110000")] 141 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 142 | internal interface ICryptoGetTextPassword2 143 | { 144 | /// 145 | /// Sets password for the archive 146 | /// 147 | /// Specifies whether archive has a password or not (0 if not) 148 | /// Password for the archive 149 | /// Zero if everything is OK 150 | [PreserveSig] 151 | int CryptoGetTextPassword2( 152 | ref int passwordIsDefined, 153 | [MarshalAs(UnmanagedType.BStr)] out string password); 154 | } 155 | 156 | internal enum AskMode : int 157 | { 158 | kExtract = 0, 159 | kTest, 160 | kSkip 161 | } 162 | 163 | internal enum OperationResult : int 164 | { 165 | kOK = 0, 166 | kUnSupportedMethod, 167 | kDataError, 168 | kCRCError 169 | } 170 | 171 | [ComImport] 172 | [Guid("23170F69-40C1-278A-0000-000600300000")] 173 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 174 | internal interface IArchiveOpenVolumeCallback 175 | { 176 | void GetProperty( 177 | ItemPropId propID, // PROPID 178 | IntPtr value); // PROPVARIANT 179 | 180 | [PreserveSig] 181 | int GetStream( 182 | [MarshalAs(UnmanagedType.LPWStr)] string name, 183 | [MarshalAs(UnmanagedType.Interface)] out IInStream inStream); 184 | } 185 | 186 | [ComImport] 187 | [Guid("23170F69-40C1-278A-0000-000600400000")] 188 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 189 | internal interface IInArchiveGetStream 190 | { 191 | [return: MarshalAs(UnmanagedType.Interface)] 192 | ISequentialInStream GetStream(uint index); 193 | } 194 | 195 | [ComImport] 196 | [Guid("23170F69-40C1-278A-0000-000300010000")] 197 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 198 | internal interface ISequentialInStream 199 | { 200 | //[PreserveSig] 201 | //int Read( 202 | // [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] byte[] data, 203 | // uint size, 204 | // IntPtr processedSize); // ref uint processedSize 205 | 206 | uint Read( 207 | [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] byte[] data, 208 | uint size); 209 | 210 | /* 211 | Out: if size != 0, return_value = S_OK and (*processedSize == 0), 212 | then there are no more bytes in stream. 213 | if (size > 0) && there are bytes in stream, 214 | this function must read at least 1 byte. 215 | This function is allowed to read less than number of remaining bytes in stream. 216 | You must call Read function in loop, if you need exact amount of data 217 | */ 218 | } 219 | 220 | [ComImport] 221 | [Guid("23170F69-40C1-278A-0000-000300020000")] 222 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 223 | internal interface ISequentialOutStream 224 | { 225 | [PreserveSig] 226 | int Write( 227 | [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] byte[] data, 228 | uint size, 229 | IntPtr processedSize); // ref uint processedSize 230 | /* 231 | if (size > 0) this function must write at least 1 byte. 232 | This function is allowed to write less than "size". 233 | You must call Write function in loop, if you need to write exact amount of data 234 | */ 235 | } 236 | 237 | [ComImport] 238 | [Guid("23170F69-40C1-278A-0000-000300030000")] 239 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 240 | internal interface IInStream //: ISequentialInStream 241 | { 242 | //[PreserveSig] 243 | //int Read( 244 | // [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] byte[] data, 245 | // uint size, 246 | // IntPtr processedSize); // ref uint processedSize 247 | 248 | uint Read( 249 | [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] byte[] data, 250 | uint size); 251 | 252 | //[PreserveSig] 253 | void Seek( 254 | long offset, 255 | uint seekOrigin, 256 | IntPtr newPosition); // ref long newPosition 257 | } 258 | 259 | [ComImport] 260 | [Guid("23170F69-40C1-278A-0000-000300040000")] 261 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 262 | internal interface IOutStream //: ISequentialOutStream 263 | { 264 | [PreserveSig] 265 | int Write( 266 | [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] byte[] data, 267 | uint size, 268 | IntPtr processedSize); // ref uint processedSize 269 | 270 | //[PreserveSig] 271 | void Seek( 272 | long offset, 273 | uint seekOrigin, 274 | IntPtr newPosition); // ref long newPosition 275 | 276 | [PreserveSig] 277 | int SetSize(long newSize); 278 | } 279 | 280 | internal enum ItemPropId : uint 281 | { 282 | kpidNoProperty = 0, 283 | 284 | kpidHandlerItemIndex = 2, 285 | kpidPath, 286 | kpidName, 287 | kpidExtension, 288 | kpidIsFolder, 289 | kpidSize, 290 | kpidPackedSize, 291 | kpidAttributes, 292 | kpidCreationTime, 293 | kpidLastAccessTime, 294 | kpidLastWriteTime, 295 | kpidSolid, 296 | kpidCommented, 297 | kpidEncrypted, 298 | kpidSplitBefore, 299 | kpidSplitAfter, 300 | kpidDictionarySize, 301 | kpidCRC, 302 | kpidType, 303 | kpidIsAnti, 304 | kpidMethod, 305 | kpidHostOS, 306 | kpidFileSystem, 307 | kpidUser, 308 | kpidGroup, 309 | kpidBlock, 310 | kpidComment, 311 | kpidPosition, 312 | kpidPrefix, 313 | 314 | kpidTotalSize = 0x1100, 315 | kpidFreeSpace, 316 | kpidClusterSize, 317 | kpidVolumeName, 318 | 319 | kpidLocalName = 0x1200, 320 | kpidProvider, 321 | 322 | kpidUserDefined = 0x10000 323 | } 324 | 325 | 326 | [ComImport] 327 | [Guid("23170F69-40C1-278A-0000-000600600000")] 328 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 329 | //[AutomationProxy(true)] 330 | internal interface IInArchive 331 | { 332 | [PreserveSig] 333 | int Open( 334 | IInStream stream, 335 | /*[MarshalAs(UnmanagedType.U8)]*/ [In] ref ulong maxCheckStartPosition, 336 | [MarshalAs(UnmanagedType.Interface)] IArchiveOpenCallback openArchiveCallback); 337 | 338 | void Close(); 339 | //void GetNumberOfItems([In] ref uint numItem); 340 | uint GetNumberOfItems(); 341 | 342 | void GetProperty( 343 | uint index, 344 | ItemPropId propID, // PROPID 345 | ref PropVariant value); // PROPVARIANT 346 | 347 | [PreserveSig] 348 | int Extract( 349 | [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] uint[] indices, //[In] ref uint indices, 350 | uint numItems, 351 | int testMode, 352 | [MarshalAs(UnmanagedType.Interface)] IArchiveExtractCallback extractCallback); 353 | 354 | // indices must be sorted 355 | // numItems = 0xFFFFFFFF means all files 356 | // testMode != 0 means "test files operation" 357 | 358 | void GetArchiveProperty( 359 | uint propID, // PROPID 360 | ref PropVariant value); // PROPVARIANT 361 | 362 | //void GetNumberOfProperties([In] ref uint numProperties); 363 | uint GetNumberOfProperties(); 364 | 365 | void GetPropertyInfo( 366 | uint index, 367 | [MarshalAs(UnmanagedType.BStr)] out string name, 368 | out ItemPropId propID, // PROPID 369 | out ushort varType); //VARTYPE 370 | 371 | //void GetNumberOfArchiveProperties([In] ref uint numProperties); 372 | uint GetNumberOfArchiveProperties(); 373 | 374 | void GetArchivePropertyInfo( 375 | uint index, 376 | [MarshalAs(UnmanagedType.BStr)] string name, 377 | ref uint propID, // PROPID 378 | ref ushort varType); //VARTYPE 379 | } 380 | 381 | internal enum ArchivePropId : uint 382 | { 383 | kName = 0, 384 | kClassID, 385 | kExtension, 386 | kAddExtension, 387 | kUpdate, 388 | kKeepName, 389 | kStartSignature, 390 | kFinishSignature, 391 | kAssociate 392 | } 393 | 394 | [UnmanagedFunctionPointer(CallingConvention.StdCall)] 395 | internal delegate int CreateObjectDelegate( 396 | [In] ref Guid classID, 397 | [In] ref Guid interfaceID, 398 | //out IntPtr outObject); 399 | [MarshalAs(UnmanagedType.Interface)] out object outObject); 400 | 401 | [UnmanagedFunctionPointer(CallingConvention.StdCall)] 402 | internal delegate int GetHandlerPropertyDelegate( 403 | ArchivePropId propID, 404 | ref PropVariant value); // PROPVARIANT 405 | 406 | [UnmanagedFunctionPointer(CallingConvention.StdCall)] 407 | internal delegate int GetNumberOfFormatsDelegate(out uint numFormats); 408 | 409 | [UnmanagedFunctionPointer(CallingConvention.StdCall)] 410 | internal delegate int GetHandlerProperty2Delegate( 411 | uint formatIndex, 412 | ArchivePropId propID, 413 | ref PropVariant value); // PROPVARIANT 414 | 415 | internal class StreamWrapper : IDisposable 416 | { 417 | protected Stream BaseStream; 418 | 419 | protected StreamWrapper(Stream baseStream) 420 | { 421 | this.BaseStream = baseStream; 422 | } 423 | 424 | public void Dispose() 425 | { 426 | this.BaseStream.Close(); 427 | } 428 | 429 | public virtual void Seek(long offset, uint seekOrigin, IntPtr newPosition) 430 | { 431 | long Position = this.BaseStream.Seek(offset, (SeekOrigin) seekOrigin); 432 | 433 | if (newPosition != IntPtr.Zero) 434 | { 435 | Marshal.WriteInt64(newPosition, Position); 436 | } 437 | } 438 | } 439 | 440 | internal class InStreamWrapper : StreamWrapper, ISequentialInStream, IInStream 441 | { 442 | public InStreamWrapper(Stream baseStream) : base(baseStream) 443 | { 444 | } 445 | 446 | public uint Read(byte[] data, uint size) 447 | { 448 | return (uint) this.BaseStream.Read(data, 0, (int) size); 449 | } 450 | } 451 | 452 | internal class OutStreamWrapper : StreamWrapper, ISequentialOutStream, IOutStream 453 | { 454 | public OutStreamWrapper(Stream baseStream) : base(baseStream) 455 | { 456 | } 457 | 458 | public int SetSize(long newSize) 459 | { 460 | this.BaseStream.SetLength(newSize); 461 | return 0; 462 | } 463 | 464 | public int Write(byte[] data, uint size, IntPtr processedSize) 465 | { 466 | this.BaseStream.Write(data, 0, (int) size); 467 | 468 | if (processedSize != IntPtr.Zero) 469 | { 470 | Marshal.WriteInt32(processedSize, (int) size); 471 | } 472 | 473 | return 0; 474 | } 475 | } 476 | } -------------------------------------------------------------------------------- /SevenZipExtractor/x64/7z.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adoconnection/SevenZipExtractor/95c469c9554ffa5218f8771ded9dc4b58dba8819/SevenZipExtractor/x64/7z.dll -------------------------------------------------------------------------------- /SevenZipExtractor/x86/7z.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adoconnection/SevenZipExtractor/95c469c9554ffa5218f8771ded9dc4b58dba8819/SevenZipExtractor/x86/7z.dll --------------------------------------------------------------------------------