diff --git a/SevenZip.Tests/MiscellaneousTests.cs b/SevenZip.Tests/MiscellaneousTests.cs index 32af147..f5715b3 100644 --- a/SevenZip.Tests/MiscellaneousTests.cs +++ b/SevenZip.Tests/MiscellaneousTests.cs @@ -15,20 +15,21 @@ public class MiscellaneousTests : TestBase [Test] public void SerializationTest() { - var ex = new ArgumentException("blahblah"); - var bf = new BinaryFormatter(); + var argumentException = new ArgumentException("blahblah"); + var binaryFormatter = new BinaryFormatter(); using (var ms = new MemoryStream()) { using (var fileStream = File.Create(TemporaryFile)) { - bf.Serialize(ms, ex); - SevenZipCompressor cmpr = new SevenZipCompressor(); - cmpr.CompressStream(ms, fileStream); + binaryFormatter.Serialize(ms, argumentException); + var compressor = new SevenZipCompressor(); + compressor.CompressStream(ms, fileStream); } } } +#if SFX [Test] public void CreateSfxArchiveTest([Values]SfxModule sfxModule) { @@ -59,6 +60,7 @@ public void CreateSfxArchiveTest([Values]SfxModule sfxModule) process?.Kill(); }); } +#endif [Test] public void LzmaEncodeDecodeTest() diff --git a/SevenZip.Tests/SevenZip.Tests.csproj b/SevenZip.Tests/SevenZip.Tests.csproj index 2cbc070..f8ace8a 100644 --- a/SevenZip.Tests/SevenZip.Tests.csproj +++ b/SevenZip.Tests/SevenZip.Tests.csproj @@ -1,17 +1,21 @@  - netstandard2.0;net45 + net45 SevenZip.Tests - SevenZipzTests - Copyright © 2018 + SevenZipTests + Copyright © Joel Ahlgren 2021 ..\Stage\obj\$(Configuration)\ ..\Stage\$(Configuration)\ - - true - - SevenZipTests.snk + Debug;Release;LiteDebug;LiteRelease + + + SFX + + + SFX + true diff --git a/SevenZip.Tests/SevenZipExtractorTests.cs b/SevenZip.Tests/SevenZipExtractorTests.cs index 6c052f1..94b7d78 100644 --- a/SevenZip.Tests/SevenZipExtractorTests.cs +++ b/SevenZip.Tests/SevenZipExtractorTests.cs @@ -198,6 +198,34 @@ public void ExtractArchiveWithLongPath() } } + [Test] + public void ReadArchivedFileNames() + { + using (var extractor = new SevenZipExtractor(@"TestData\multiple_files.7z")) + { + var fileNames = extractor.ArchiveFileNames; + Assert.AreEqual(3, fileNames.Count); + + Assert.AreEqual("file1.txt", fileNames[0]); + Assert.AreEqual("file2.txt", fileNames[1]); + Assert.AreEqual("file3.txt", fileNames[2]); + } + } + + [Test] + public void ReadArchivedFileData() + { + using (var extractor = new SevenZipExtractor(@"TestData\multiple_files.7z")) + { + var fileData = extractor.ArchiveFileData; + Assert.AreEqual(3, fileData.Count); + + Assert.AreEqual("file1.txt", fileData[0].FileName); + Assert.IsFalse(fileData[0].Encrypted); + Assert.IsFalse(fileData[0].IsDirectory); + } + } + [Test, TestCaseSource(nameof(TestFiles))] public void ExtractDifferentFormatsTest(TestFile file) { diff --git a/SevenZip.sln b/SevenZip.sln index 991573a..06b53bc 100644 --- a/SevenZip.sln +++ b/SevenZip.sln @@ -10,24 +10,36 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{043464C6-413E-4D0F-8A43-B23F674B1804}" ProjectSection(SolutionItems) = preProject appveyor.yml = appveyor.yml + changelog.md = changelog.md license = license nuget.config = nuget.config - package.nuspec = package.nuspec + package.lite.nuspec = package.lite.nuspec + package.regular.nuspec = package.regular.nuspec readme.md = readme.md EndProjectSection EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU + LiteDebug|Any CPU = LiteDebug|Any CPU + LiteRelease|Any CPU = LiteRelease|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {4960DD14-3431-47EC-B9D9-9D2730A98DC3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {4960DD14-3431-47EC-B9D9-9D2730A98DC3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4960DD14-3431-47EC-B9D9-9D2730A98DC3}.LiteDebug|Any CPU.ActiveCfg = LiteDebug|Any CPU + {4960DD14-3431-47EC-B9D9-9D2730A98DC3}.LiteDebug|Any CPU.Build.0 = LiteDebug|Any CPU + {4960DD14-3431-47EC-B9D9-9D2730A98DC3}.LiteRelease|Any CPU.ActiveCfg = LiteRelease|Any CPU + {4960DD14-3431-47EC-B9D9-9D2730A98DC3}.LiteRelease|Any CPU.Build.0 = LiteRelease|Any CPU {4960DD14-3431-47EC-B9D9-9D2730A98DC3}.Release|Any CPU.ActiveCfg = Release|Any CPU {4960DD14-3431-47EC-B9D9-9D2730A98DC3}.Release|Any CPU.Build.0 = Release|Any CPU {67192E62-C7FE-485F-BEC4-05734A943FAA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {67192E62-C7FE-485F-BEC4-05734A943FAA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {67192E62-C7FE-485F-BEC4-05734A943FAA}.LiteDebug|Any CPU.ActiveCfg = LiteDebug|Any CPU + {67192E62-C7FE-485F-BEC4-05734A943FAA}.LiteDebug|Any CPU.Build.0 = LiteDebug|Any CPU + {67192E62-C7FE-485F-BEC4-05734A943FAA}.LiteRelease|Any CPU.ActiveCfg = LiteRelease|Any CPU + {67192E62-C7FE-485F-BEC4-05734A943FAA}.LiteRelease|Any CPU.Build.0 = LiteRelease|Any CPU {67192E62-C7FE-485F-BEC4-05734A943FAA}.Release|Any CPU.ActiveCfg = Release|Any CPU {67192E62-C7FE-485F-BEC4-05734A943FAA}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection diff --git a/SevenZip/ArchiveUpdateCallback.cs b/SevenZip/ArchiveUpdateCallback.cs index 5c180b7..cb127db 100644 --- a/SevenZip/ArchiveUpdateCallback.cs +++ b/SevenZip/ArchiveUpdateCallback.cs @@ -681,10 +681,10 @@ public void SetOperationResult(OperationResult operationResult) AddException(new ExtractionFailedException("File is corrupted. Crc check has failed.")); break; case OperationResult.DataError: - AddException(new ExtractionFailedException("File is corrupted. Data error has occured.")); + AddException(new ExtractionFailedException("File is corrupted. Data error has occurred.")); break; case OperationResult.UnsupportedMethod: - AddException(new ExtractionFailedException("Unsupported method error has occured.")); + AddException(new ExtractionFailedException("Unsupported method error has occurred.")); break; case OperationResult.Unavailable: AddException(new ExtractionFailedException("File is unavailable.")); @@ -711,23 +711,25 @@ public void SetOperationResult(OperationResult operationResult) } if (_fileStream != null) { - - _fileStream.BytesRead -= IntEventArgsHandler; - //Specific Zip implementation - can not Dispose files for Zip. - if (_compressor.ArchiveFormat != OutArchiveFormat.Zip) + _fileStream.BytesRead -= IntEventArgsHandler; + + //Specific Zip implementation - can not Dispose files for Zip. + if (_compressor.ArchiveFormat != OutArchiveFormat.Zip) + { + try { - try - { - _fileStream.Dispose(); - } - catch (ObjectDisposedException) {} + _fileStream.Dispose(); } - else - { - _wrappersToDispose.Add(_fileStream); - } + catch (ObjectDisposedException) {} + } + else + { + _wrappersToDispose.Add(_fileStream); + } + _fileStream = null; } + OnFileCompressionFinished(EventArgs.Empty); } diff --git a/SevenZip/COM.cs b/SevenZip/COM.cs index 2804a97..3bbe9c1 100644 --- a/SevenZip/COM.cs +++ b/SevenZip/COM.cs @@ -5,7 +5,9 @@ using System.Globalization; using System.IO; using System.Runtime.InteropServices; +#if NET45 || NETSTANDARD2_0 using System.Security.Permissions; +#endif using FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME; #if UNMANAGED @@ -120,11 +122,14 @@ public object Object { get { +#if NET45 || NETSTANDARD2_0 var sp = new SecurityPermission(SecurityPermissionFlag.UnmanagedCode); sp.Demand(); - +#endif switch (VarType) { + case VarEnum.VT_BSTR: + return Marshal.PtrToStringBSTR(Value); case VarEnum.VT_EMPTY: return null; case VarEnum.VT_FILETIME: @@ -137,7 +142,8 @@ public object Object return DateTime.MinValue; } default: - GCHandle propHandle = GCHandle.Alloc(this, GCHandleType.Pinned); + var propHandle = GCHandle.Alloc(this, GCHandleType.Pinned); + try { return Marshal.GetObjectForNativeVariant(propHandle.AddrOfPinnedObject()); @@ -173,7 +179,7 @@ public object Object /// true if the specified System.Object is equal to the current PropVariant; otherwise, false. public override bool Equals(object obj) { - return (obj is PropVariant variant) && Equals(variant); + return obj is PropVariant variant && Equals(variant); } /// @@ -187,10 +193,12 @@ private bool Equals(PropVariant afi) { return false; } + if (VarType != VarEnum.VT_BSTR) { return afi.Int64Value == Int64Value; } + return afi.Value == Value; } @@ -268,11 +276,11 @@ public enum OperationResult /// UnsupportedMethod, /// - /// Data error has occured + /// Data error has occurred /// DataError, /// - /// CrcError has occured + /// CrcError has occurred /// CrcError, /// @@ -577,7 +585,7 @@ internal static class PropIdToName /// PropId string names /// public static readonly Dictionary PropIdNames = - #region Initialization +#region Initialization new Dictionary(46) { {ItemPropId.Path, "Path"}, @@ -648,7 +656,7 @@ internal static class PropIdToName {ItemPropId.FreeSpace, "Free Space"}, {ItemPropId.ClusterSize, "Cluster Size"} }; - #endregion +#endregion } /// @@ -801,7 +809,7 @@ internal interface IArchiveUpdateCallback /// Gets the archive item property data. /// /// Item index - /// Property identificator + /// Property identifier /// Property value /// Zero if Ok [PreserveSig] @@ -1132,4 +1140,4 @@ internal interface ISetProperties int SetProperties(IntPtr names, IntPtr values, int numProperties); } #endif -} + } diff --git a/SevenZip/LibraryManager.cs b/SevenZip/LibraryManager.cs index 8ed2cd8..05897ff 100644 --- a/SevenZip/LibraryManager.cs +++ b/SevenZip/LibraryManager.cs @@ -4,7 +4,9 @@ namespace SevenZip using System.Collections.Generic; using System.Configuration; using System.Diagnostics; +#if NET45 || NETSTANDARD2_0 using System.Security.Permissions; +#endif using System.IO; using System.Reflection; using System.Runtime.InteropServices; @@ -59,12 +61,8 @@ private static string DetermineLibraryFilePath() private static LibraryFeature? _features; private static Dictionary> _inArchives; - private static Dictionary> _outArchives; - private static int _totalUsers; - - // private static string _LibraryVersion; private static bool? _modifyCapable; private static void InitUserInFormat(object user, InArchiveFormat format) @@ -73,6 +71,7 @@ private static void InitUserInFormat(object user, InArchiveFormat format) { _inArchives.Add(user, new Dictionary()); } + if (!_inArchives[user].ContainsKey(format)) { _inArchives[user].Add(format, null); @@ -86,6 +85,7 @@ private static void InitUserOutFormat(object user, OutArchiveFormat format) { _outArchives.Add(user, new Dictionary()); } + if (!_outArchives[user].ContainsKey(format)) { _outArchives[user].Add(format, null); @@ -124,10 +124,12 @@ public static void LoadLibrary(object user, Enum format) { throw new SevenZipLibraryException("DLL file does not exist."); } + if ((_modulePtr = NativeMethods.LoadLibrary(_libraryFileName)) == IntPtr.Zero) { throw new SevenZipLibraryException($"failed to load library from \"{_libraryFileName}\"."); } + if (NativeMethods.GetProcAddress(_modulePtr, "GetHandlerProperty") == IntPtr.Zero) { NativeMethods.FreeLibrary(_modulePtr); @@ -147,8 +149,7 @@ public static void LoadLibrary(object user, Enum format) return; } - throw new ArgumentException( - "Enum " + format + " is not a valid archive format attribute!"); + throw new ArgumentException($"Enum {format} is not a valid archive format attribute!"); } } @@ -168,9 +169,10 @@ public static bool ModifyCapable _libraryFileName = DetermineLibraryFilePath(); } - FileVersionInfo dllVersionInfo = FileVersionInfo.GetVersionInfo(_libraryFileName); + var dllVersionInfo = FileVersionInfo.GetVersionInfo(_libraryFileName); _modifyCapable = dllVersionInfo.FileMajorPart >= 9; } + return _modifyCapable.Value; } } @@ -183,39 +185,38 @@ private static string GetResourceString(string str) return Namespace + ".arch." + str; } - private static bool ExtractionBenchmark(string archiveFileName, Stream outStream, - ref LibraryFeature? features, LibraryFeature testedFeature) + private static bool ExtractionBenchmark(string archiveFileName, Stream outStream, ref LibraryFeature? features, LibraryFeature testedFeature) { - var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream( - GetResourceString(archiveFileName)); + var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(GetResourceString(archiveFileName)); + try { - using (var extr = new SevenZipExtractor(stream)) + using (var extractor = new SevenZipExtractor(stream)) { - extr.ExtractFile(0, outStream); + extractor.ExtractFile(0, outStream); } } catch (Exception) { return false; } + features |= testedFeature; return true; } - private static bool CompressionBenchmark(Stream inStream, Stream outStream, - OutArchiveFormat format, CompressionMethod method, - ref LibraryFeature? features, LibraryFeature testedFeature) + private static bool CompressionBenchmark(Stream inStream, Stream outStream, OutArchiveFormat format, CompressionMethod method, ref LibraryFeature? features, LibraryFeature testedFeature) { try { - var compr = new SevenZipCompressor { ArchiveFormat = format, CompressionMethod = method }; - compr.CompressStream(inStream, outStream); + var compressor = new SevenZipCompressor { ArchiveFormat = format, CompressionMethod = method }; + compressor.CompressStream(inStream, outStream); } catch (Exception) { return false; } + features |= testedFeature; return true; } @@ -344,65 +345,70 @@ public static LibraryFeature CurrentLibraryFeatures /// Archive format public static void FreeLibrary(object user, Enum format) { +#if NET45 || NETSTANDARD2_0 var sp = new SecurityPermission(SecurityPermissionFlag.UnmanagedCode); sp.Demand(); - +#endif lock (_syncRoot) { if (_modulePtr != IntPtr.Zero) - { - if (format is InArchiveFormat archiveFormat) { - if (_inArchives != null && _inArchives.ContainsKey(user) && - _inArchives[user].ContainsKey(archiveFormat) && - _inArchives[user][archiveFormat] != null) + if (format is InArchiveFormat archiveFormat) { - try - { - Marshal.ReleaseComObject(_inArchives[user][archiveFormat]); - } - catch (InvalidComObjectException) {} - _inArchives[user].Remove(archiveFormat); - _totalUsers--; - if (_inArchives[user].Count == 0) + if (_inArchives != null && _inArchives.ContainsKey(user) && + _inArchives[user].ContainsKey(archiveFormat) && + _inArchives[user][archiveFormat] != null) { - _inArchives.Remove(user); + try + { + Marshal.ReleaseComObject(_inArchives[user][archiveFormat]); + } + catch (InvalidComObjectException) {} + + _inArchives[user].Remove(archiveFormat); + _totalUsers--; + + if (_inArchives[user].Count == 0) + { + _inArchives.Remove(user); + } } } - } - if (format is OutArchiveFormat outArchiveFormat) - { - if (_outArchives != null && _outArchives.ContainsKey(user) && - _outArchives[user].ContainsKey(outArchiveFormat) && - _outArchives[user][outArchiveFormat] != null) + if (format is OutArchiveFormat outArchiveFormat) { - try - { - Marshal.ReleaseComObject(_outArchives[user][outArchiveFormat]); - } - catch (InvalidComObjectException) {} - _outArchives[user].Remove(outArchiveFormat); - _totalUsers--; - if (_outArchives[user].Count == 0) + if (_outArchives != null && _outArchives.ContainsKey(user) && + _outArchives[user].ContainsKey(outArchiveFormat) && + _outArchives[user][outArchiveFormat] != null) { - _outArchives.Remove(user); + try + { + Marshal.ReleaseComObject(_outArchives[user][outArchiveFormat]); + } + catch (InvalidComObjectException) {} + + _outArchives[user].Remove(outArchiveFormat); + _totalUsers--; + + if (_outArchives[user].Count == 0) + { + _outArchives.Remove(user); + } } } - } - if ((_inArchives == null || _inArchives.Count == 0) && (_outArchives == null || _outArchives.Count == 0)) - { - _inArchives = null; - _outArchives = null; - - if (_totalUsers == 0) + if ((_inArchives == null || _inArchives.Count == 0) && (_outArchives == null || _outArchives.Count == 0)) { - NativeMethods.FreeLibrary(_modulePtr); - _modulePtr = IntPtr.Zero; + _inArchives = null; + _outArchives = null; + + if (_totalUsers == 0) + { + NativeMethods.FreeLibrary(_modulePtr); + _modulePtr = IntPtr.Zero; + } } } - } } } @@ -417,8 +423,10 @@ public static IInArchive InArchive(InArchiveFormat format, object user) { if (_inArchives[user][format] == null) { +#if NET45 || NETSTANDARD2_0 var sp = new SecurityPermission(SecurityPermissionFlag.UnmanagedCode); sp.Demand(); +#endif if (_modulePtr == IntPtr.Zero) { @@ -439,10 +447,10 @@ public static IInArchive InArchive(InArchiveFormat format, object user) { throw new SevenZipLibraryException(); } - object result; - Guid interfaceId = typeof(IInArchive).GUID; - Guid classID = Formats.InFormatGuids[format]; + object result; + var interfaceId = typeof(IInArchive).GUID; + var classID = Formats.InFormatGuids[format]; try { @@ -472,32 +480,34 @@ public static IOutArchive OutArchive(OutArchiveFormat format, object user) { if (_outArchives[user][format] == null) { +#if NET45 || NETSTANDARD2_0 var sp = new SecurityPermission(SecurityPermissionFlag.UnmanagedCode); sp.Demand(); +#endif if (_modulePtr == IntPtr.Zero) { throw new SevenZipLibraryException(); } + var createObject = (NativeMethods.CreateObjectDelegate) Marshal.GetDelegateForFunctionPointer( NativeMethods.GetProcAddress(_modulePtr, "CreateObject"), typeof(NativeMethods.CreateObjectDelegate)); - object result; - Guid interfaceId = typeof(IOutArchive).GUID; - - Guid classID = Formats.OutFormatGuids[format]; + var interfaceId = typeof(IOutArchive).GUID; + try { - createObject(ref classID, ref interfaceId, out result); + var classId = Formats.OutFormatGuids[format]; + createObject(ref classId, ref interfaceId, out var result); + + InitUserOutFormat(user, format); + _outArchives[user][format] = result as IOutArchive; } catch (Exception) { throw new SevenZipLibraryException("Your 7-zip library does not support this archive type."); } - - InitUserOutFormat(user, format); - _outArchives[user][format] = result as IOutArchive; } return _outArchives[user][format]; @@ -506,17 +516,16 @@ public static IOutArchive OutArchive(OutArchiveFormat format, object user) public static void SetLibraryPath(string libraryPath) { - if (_modulePtr != IntPtr.Zero && !Path.GetFullPath(libraryPath).Equals( - Path.GetFullPath(_libraryFileName), StringComparison.OrdinalIgnoreCase)) + if (_modulePtr != IntPtr.Zero && !Path.GetFullPath(libraryPath).Equals(Path.GetFullPath(_libraryFileName), StringComparison.OrdinalIgnoreCase)) { - throw new SevenZipLibraryException( - "can not change the library path while the library \"" + _libraryFileName + "\" is being used."); + throw new SevenZipLibraryException($"can not change the library path while the library \"{_libraryFileName}\" is being used."); } + if (!File.Exists(libraryPath)) { - throw new SevenZipLibraryException( - "can not change the library path because the file \"" + libraryPath + "\" does not exist."); + throw new SevenZipLibraryException($"can not change the library path because the file \"{libraryPath}\" does not exist."); } + _libraryFileName = libraryPath; _features = null; } diff --git a/SevenZip/NativeMethods.cs b/SevenZip/NativeMethods.cs index 76c14d4..8ec8f3b 100644 --- a/SevenZip/NativeMethods.cs +++ b/SevenZip/NativeMethods.cs @@ -6,16 +6,12 @@ namespace SevenZip #if UNMANAGED internal static class NativeMethods { - #region Delegates - [UnmanagedFunctionPointer(CallingConvention.StdCall)] public delegate int CreateObjectDelegate( [In] ref Guid classID, [In] ref Guid interfaceID, [MarshalAs(UnmanagedType.Interface)] out object outObject); - #endregion - [DllImport("kernel32.dll", BestFitMapping = false, ThrowOnUnmappableChar = true)] public static extern IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)] string fileName); @@ -29,6 +25,7 @@ internal static class NativeMethods public static T SafeCast(PropVariant var, T def) { object obj; + try { obj = var.Object; @@ -37,10 +34,12 @@ public static T SafeCast(PropVariant var, T def) { return def; } - if (obj != null && obj is T) + + if (obj is T expected) { - return (T) obj; - } + return expected; + } + return def; } } diff --git a/SevenZip/SevenZip.csproj b/SevenZip/SevenZip.csproj index 0623e62..5a486e5 100644 --- a/SevenZip/SevenZip.csproj +++ b/SevenZip/SevenZip.csproj @@ -1,53 +1,35 @@ - + - 9.0.30729 SevenZipSharp - netstandard2.0;net45 + netstandard2.0;net45;netcoreapp3.1 true SevenZip.snk - - - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - false - true SevenZipSharp Markovtsev Vadim SevenZipSharp 7-zip native library wrapper - Copyright (C) Markovtsev Vadim 2009, 2010, licenced under LGPLv3 - 0.64 - 0.64 + Copyright (C) Markovtsev Vadim 2009, 2010, licensed under LGPLv3 ..\Stage\obj\$(Configuration)\ ..\Stage\$(Configuration)\ + ..\Stage\$(Configuration)\SevenZipSharp.xml false + $(DefaultItemExcludes);sfx\* + Debug;Release;LiteDebug;LiteRelease - TRACE;DEBUG;UNMANAGED - ..\Stage\$(Configuration)\SevenZip.XML + TRACE;DEBUG;UNMANAGED;SFX + TRACE;UNMANAGED;SFX + true + + + TRACE;DEBUG;UNMANAGED + + TRACE;UNMANAGED true - - - - - - - PreserveNewest @@ -55,15 +37,26 @@ PreserveNewest - - + - + + + + + + + + + + + + + @@ -72,22 +65,14 @@ + - - - - - - - - - - + - + diff --git a/SevenZip/SevenZipBase.cs b/SevenZip/SevenZipBase.cs index 87acae5..3d72e6f 100644 --- a/SevenZip/SevenZipBase.cs +++ b/SevenZip/SevenZipBase.cs @@ -212,6 +212,9 @@ internal void CheckedExecute(int hresult, string message, CallbackBase handler) switch (hresult) { + case -2146233067: + exception = new SevenZipException("Operation is not supported. (0x80131515: E_NOTSUPPORTED)"); + break; case -2147024784: exception = new SevenZipException("There is not enough space on the disk. (0x80070070: ERROR_DISK_FULL)"); break; @@ -224,6 +227,12 @@ internal void CheckedExecute(int hresult, string message, CallbackBase handler) case -2147024809: exception = new SevenZipException("Invalid arguments provided. (0x80070057: E_INVALIDARG)"); break; + case -2147467263: + exception = new SevenZipException("Functionality not implemented. (0x80004001: E_NOTIMPL)"); + break; + case -2147024891: + exception = new SevenZipException("Access is denied. (0x80070005: E_ACCESSDENIED)"); + break; default: exception = new SevenZipException( $"Execution has failed due to an internal SevenZipSharp issue (0x{hresult:x} / {hresult}).\n" + diff --git a/SevenZip/SevenZipCompressor.cs b/SevenZip/SevenZipCompressor.cs index 455f554..6b48183 100644 --- a/SevenZip/SevenZipCompressor.cs +++ b/SevenZip/SevenZipCompressor.cs @@ -6,7 +6,9 @@ namespace SevenZip using System.IO; using System.Linq; using System.Runtime.InteropServices; +#if NET45 || NETSTANDARD2_0 using System.Security.Permissions; +#endif using SevenZip.Sdk; using SevenZip.Sdk.Compression.Lzma; @@ -25,7 +27,7 @@ public sealed partial class SevenZipCompressor { #if UNMANAGED - #region Fields +#region Fields private bool _compressingFilesOnDisk; @@ -101,7 +103,7 @@ public sealed partial class SevenZipCompressor /// public bool FastCompression { get; set; } - #endregion +#endregion #endif private static volatile int _lzmaDictionarySize = 1 << 22; @@ -175,7 +177,7 @@ private static void ValidateStream(Stream stream) #if UNMANAGED - #region Private functions +#region Private functions private IOutArchive MakeOutArchive(IInStream inArchiveStream) { @@ -211,6 +213,8 @@ private bool MethodIsValid(CompressionMethod method) return true; } + // TODO: Decide what to do with a returned "false" from this method! + switch (_archiveFormat) { case OutArchiveFormat.GZip: @@ -229,6 +233,10 @@ private bool MethodIsValid(CompressionMethod method) { return method == CompressionMethod.Copy; } + case OutArchiveFormat.Zip: + { + return method != CompressionMethod.Lzma2; + } default: { return true; @@ -272,7 +280,7 @@ private void SetCompressionProperties() throw new CompressionFailedException("Unfortunately, the creation of multi-volume non-7Zip archives is not implemented."); } - #region Check for "forbidden" parameters +#region Check for "forbidden" parameters if (CustomParameters.ContainsKey("x")) { @@ -298,16 +306,19 @@ private void SetCompressionProperties() } } - #endregion +#endregion var names = new List(2 + CustomParameters.Count); var values = new List(2 + CustomParameters.Count); + +#if NET45 || NETSTANDARD2_0 var sp = new SecurityPermission(SecurityPermissionFlag.UnmanagedCode); sp.Demand(); +#endif - #region Initialize compression properties +#region Initialize compression properties - names.Add(Marshal.StringToBSTR("x")); + names.Add(Marshal.StringToBSTR("x")); values.Add(new PropVariant()); if (_compressionMethod != CompressionMethod.Default) @@ -339,25 +350,7 @@ private void SetCompressionProperties() names.Add(Marshal.StringToBSTR(pair.Key)); var pv = new PropVariant(); - #region List of parameters to cast as integers - - var integerParameters = new HashSet - { - "fb", - "pass", - "o", - "yx", - "a", - "mc", - "lc", - "lp", - "pb", - "cp" - }; - - #endregion - - if (integerParameters.Contains(pair.Key)) + if (pair.Value.All(char.IsDigit)) { pv.VarType = VarEnum.VT_UI4; pv.UInt32Value = Convert.ToUInt32(pair.Value, CultureInfo.InvariantCulture); @@ -371,9 +364,9 @@ private void SetCompressionProperties() values.Add(pv); } - #endregion +#endregion - #region Set compression level +#region Set compression level var clpv = values[0]; clpv.VarType = VarEnum.VT_UI4; @@ -414,9 +407,9 @@ private void SetCompressionProperties() values[0] = clpv; - #endregion +#endregion - #region Encrypt headers +#region Encrypt headers if (EncryptHeaders && _archiveFormat == OutArchiveFormat.SevenZip && !SwitchIsInCustomParameters("he")) { @@ -425,9 +418,9 @@ private void SetCompressionProperties() values.Add(tmp); } - #endregion +#endregion - #region Zip Encryption +#region Zip Encryption if (_archiveFormat == OutArchiveFormat.Zip && ZipEncryptionMethod != ZipEncryptionMethod.ZipCrypto && @@ -444,7 +437,7 @@ private void SetCompressionProperties() values.Add(tmp); } - #endregion +#endregion var namesHandle = GCHandle.Alloc(names.ToArray(), GCHandleType.Pinned); var valuesHandle = GCHandle.Alloc(values.ToArray(), GCHandleType.Pinned); @@ -691,9 +684,9 @@ private void AddFilesFromDirectory(string directory, ICollection files, } } - #endregion +#endregion - #region GetArchiveUpdateCallback overloads +#region GetArchiveUpdateCallback overloads /// /// Performs the common ArchiveUpdateCallback initialization. @@ -860,9 +853,9 @@ private ArchiveUpdateCallback GetArchiveUpdateCallback(Stream inStream, string p return auc; } - #endregion +#endregion - #region Service "Get" functions +#region Service "Get" functions private void FreeCompressionCallback(ArchiveUpdateCallback callback) { @@ -961,11 +954,11 @@ private ArchiveOpenCallback GetArchiveOpenCallback() : new ArchiveOpenCallback(_archiveName, Password); } - #endregion +#endregion - #region Core public Members +#region Core public Members - #region Events +#region Events /// /// Occurs when the next file is going to be packed. @@ -995,7 +988,7 @@ private ArchiveOpenCallback GetArchiveOpenCallback() /// public event EventHandler CompressionFinished; - #region Event proxies +#region Event proxies /// /// Event proxy for FileCompressionStarted. @@ -1037,11 +1030,11 @@ private void FilesFoundEventProxy(object sender, IntEventArgs e) OnEvent(FilesFound, e, false); } - #endregion +#endregion - #endregion +#endregion - #region Properties +#region Properties /// /// Gets or sets the archive format @@ -1081,9 +1074,9 @@ public long VolumeSize set => _volumeSize = value > 0 ? value : 0; } - #endregion +#endregion - #region CompressFiles overloads +#region CompressFiles overloads /// /// Packs files into the archive. @@ -1298,9 +1291,9 @@ public void CompressFilesEncrypted(string archiveName, int commonRootLength, str ThrowUserException(); } - #endregion +#endregion - #region CompressDirectory overloads +#region CompressDirectory overloads /// /// Packs all files in the specified directory. @@ -1384,9 +1377,9 @@ public void CompressDirectory(string directory, Stream archiveStream, string pas CompressFilesEncrypted(archiveStream, commonRootLength, password, files.ToArray()); } - #endregion +#endregion - #region CompressFileDictionary overloads +#region CompressFileDictionary overloads /// /// Packs the specified file dictionary. @@ -1450,9 +1443,9 @@ public void CompressFileDictionary(IDictionary fileDictionary, S CompressStreamDictionary(streamDict, archiveStream, password); } - #endregion +#endregion - #region CompressStreamDictionary overloads +#region CompressStreamDictionary overloads /// /// Packs the specified stream dictionary. @@ -1580,9 +1573,9 @@ public void CompressStreamDictionary(IDictionary streamDictionar ThrowUserException(); } - #endregion +#endregion - #region CompressStream overloads +#region CompressStream overloads /// /// Compresses the specified stream. @@ -1635,9 +1628,9 @@ public void CompressStream(Stream inStream, Stream outStream, string password = ThrowUserException(); } - #endregion +#endregion - #region ModifyArchive overloads +#region ModifyArchive overloads /// /// Modifies the existing archive (renames files or deletes them). @@ -1758,9 +1751,9 @@ public void ModifyArchive(string archiveName, IDictionary newFileNa ThrowUserException(); } - #endregion +#endregion - #endregion +#endregion #endif @@ -1775,7 +1768,7 @@ public static int LzmaDictionarySize internal static void WriteLzmaProperties(Encoder encoder) { - #region LZMA properties definition +#region LZMA properties definition CoderPropId[] propIDs = { @@ -1800,7 +1793,7 @@ internal static void WriteLzmaProperties(Encoder encoder) false }; - #endregion +#endregion encoder.SetCoderProperties(propIDs, properties); } diff --git a/SevenZip/SevenZipCompressorAsynchronous.cs b/SevenZip/SevenZipCompressorAsynchronous.cs index c8f9893..a6d8525 100644 --- a/SevenZip/SevenZipCompressorAsynchronous.cs +++ b/SevenZip/SevenZipCompressorAsynchronous.cs @@ -146,11 +146,17 @@ public void BeginCompressFilesEncrypted(Stream archiveStream, int commonRootLeng /// /// Array of file names to pack. /// The archive file name. - public Task CompressFilesAsync(string archiveName, params string[] fileFullNames) + public async Task CompressFilesAsync(string archiveName, params string[] fileFullNames) { - SaveContext(); - return Task.Run(() => new CompressFiles1Delegate(CompressFiles).Invoke(archiveName, fileFullNames)) - .ContinueWith(_ => ReleaseContext()); + try + { + SaveContext(); + await Task.Run(() => new CompressFiles1Delegate(CompressFiles).Invoke(archiveName, fileFullNames)); + } + finally + { + ReleaseContext(); + } } /// @@ -159,11 +165,17 @@ public Task CompressFilesAsync(string archiveName, params string[] fileFullNames /// Array of file names to pack. /// The archive output stream. /// Use CompressFiles(string archiveName ... ) overloads for archiving to disk. - public Task CompressFilesAsync(Stream archiveStream, params string[] fileFullNames) + public async Task CompressFilesAsync(Stream archiveStream, params string[] fileFullNames) { - SaveContext(); - return Task.Run(() => new CompressFiles2Delegate(CompressFiles).Invoke(archiveStream, fileFullNames)) - .ContinueWith(_ => ReleaseContext()); + try + { + SaveContext(); + await Task.Run(() => new CompressFiles2Delegate(CompressFiles).Invoke(archiveStream, fileFullNames)); + } + finally + { + ReleaseContext(); + } } /// @@ -172,11 +184,17 @@ public Task CompressFilesAsync(Stream archiveStream, params string[] fileFullNam /// Array of file names to pack. /// The length of the common root of the file names. /// The archive file name. - public Task CompressFilesAsync(string archiveName, int commonRootLength, params string[] fileFullNames) + public async Task CompressFilesAsync(string archiveName, int commonRootLength, params string[] fileFullNames) { - SaveContext(); - return Task.Run(() => new CompressFiles3Delegate(CompressFiles).Invoke(archiveName, commonRootLength, fileFullNames)) - .ContinueWith(_ => ReleaseContext()); + try + { + SaveContext(); + await Task.Run(() => new CompressFiles3Delegate(CompressFiles).Invoke(archiveName, commonRootLength, fileFullNames)); + } + finally + { + ReleaseContext(); + } } /// @@ -186,11 +204,17 @@ public Task CompressFilesAsync(string archiveName, int commonRootLength, params /// The length of the common root of the file names. /// The archive output stream. /// Use CompressFiles(string archiveName, ... ) overloads for archiving to disk. - public Task CompressFilesAsync(Stream archiveStream, int commonRootLength, params string[] fileFullNames) + public async Task CompressFilesAsync(Stream archiveStream, int commonRootLength, params string[] fileFullNames) { - SaveContext(); - return Task.Run(() => new CompressFiles4Delegate(CompressFiles).Invoke(archiveStream, commonRootLength, fileFullNames)) - .ContinueWith(_ => ReleaseContext()); + try + { + SaveContext(); + await Task.Run(() => new CompressFiles4Delegate(CompressFiles).Invoke(archiveStream, commonRootLength, fileFullNames)); + } + finally + { + ReleaseContext(); + } } /// @@ -199,11 +223,17 @@ public Task CompressFilesAsync(Stream archiveStream, int commonRootLength, param /// Array of file names to pack. /// The archive file name /// The archive password. - public Task CompressFilesEncryptedAsync(string archiveName, string password, params string[] fileFullNames) + public async Task CompressFilesEncryptedAsync(string archiveName, string password, params string[] fileFullNames) { - SaveContext(); - return Task.Run(() => new CompressFilesEncrypted1Delegate(CompressFilesEncrypted).Invoke(archiveName, password, fileFullNames)) - .ContinueWith(_ => ReleaseContext()); + try + { + SaveContext(); + await Task.Run(() => new CompressFilesEncrypted1Delegate(CompressFilesEncrypted).Invoke(archiveName, password, fileFullNames)); + } + finally + { + ReleaseContext(); + } } /// @@ -213,11 +243,17 @@ public Task CompressFilesEncryptedAsync(string archiveName, string password, par /// The archive output stream. /// Use CompressFiles( ... string archiveName ... ) overloads for archiving to disk. /// The archive password. - public Task CompressFilesEncryptedAsync(Stream archiveStream, string password, params string[] fileFullNames) + public async Task CompressFilesEncryptedAsync(Stream archiveStream, string password, params string[] fileFullNames) { - SaveContext(); - return Task.Run(() => new CompressFilesEncrypted2Delegate(CompressFilesEncrypted).Invoke(archiveStream, password, fileFullNames)) - .ContinueWith(_ => ReleaseContext()); + try + { + SaveContext(); + await Task.Run(() => new CompressFilesEncrypted2Delegate(CompressFilesEncrypted).Invoke(archiveStream, password, fileFullNames)); + } + finally + { + ReleaseContext(); + } } /// @@ -227,11 +263,17 @@ public Task CompressFilesEncryptedAsync(Stream archiveStream, string password, p /// The archive file name /// The archive password. /// The length of the common root of the file names. - public Task CompressFilesEncryptedAsync(string archiveName, int commonRootLength, string password, params string[] fileFullNames) + public async Task CompressFilesEncryptedAsync(string archiveName, int commonRootLength, string password, params string[] fileFullNames) { - SaveContext(); - return Task.Run(() => new CompressFilesEncrypted3Delegate(CompressFilesEncrypted).Invoke(archiveName, commonRootLength, password, fileFullNames)) - .ContinueWith(_ => ReleaseContext()); + try + { + SaveContext(); + await Task.Run(() => new CompressFilesEncrypted3Delegate(CompressFilesEncrypted).Invoke(archiveName, commonRootLength, password, fileFullNames)); + } + finally + { + ReleaseContext(); + } } /// @@ -242,11 +284,17 @@ public Task CompressFilesEncryptedAsync(string archiveName, int commonRootLength /// Use CompressFiles( ... string archiveName ... ) overloads for archiving to disk. /// The archive password. /// The length of the common root of the file names. - public Task CompressFilesEncryptedAsync(Stream archiveStream, int commonRootLength, string password, params string[] fileFullNames) + public async Task CompressFilesEncryptedAsync(Stream archiveStream, int commonRootLength, string password, params string[] fileFullNames) { - SaveContext(); - return Task.Run(() => new CompressFilesEncrypted4Delegate(CompressFilesEncrypted).Invoke(archiveStream, commonRootLength, password, fileFullNames)) - .ContinueWith(_ => ReleaseContext()); + try + { + SaveContext(); + await Task.Run(() => new CompressFilesEncrypted4Delegate(CompressFilesEncrypted).Invoke(archiveStream, commonRootLength, password, fileFullNames)); + } + finally + { + ReleaseContext(); + } } #endregion @@ -296,11 +344,17 @@ public void BeginCompressDirectory(string directory, Stream archiveStream, strin /// The archive password. /// Search string, such as "*.txt". /// If true, files will be searched for recursively; otherwise, not. - public Task CompressDirectoryAsync(string directory, string archiveName, string password = "", string searchPattern = "*", bool recursion = true) + public async Task CompressDirectoryAsync(string directory, string archiveName, string password = "", string searchPattern = "*", bool recursion = true) { - SaveContext(); - return Task.Run(() => new CompressDirectoryDelegate(CompressDirectory).Invoke(directory, archiveName, password, searchPattern, recursion)) - .ContinueWith(_ => ReleaseContext()); + try + { + SaveContext(); + await Task.Run(() => new CompressDirectoryDelegate(CompressDirectory).Invoke(directory, archiveName, password, searchPattern, recursion)); + } + finally + { + ReleaseContext(); + } } /// @@ -312,11 +366,17 @@ public Task CompressDirectoryAsync(string directory, string archiveName, string /// The archive password. /// Search string, such as "*.txt". /// If true, files will be searched for recursively; otherwise, not. - public Task CompressDirectoryAsync(string directory, Stream archiveStream, string password, string searchPattern = "*", bool recursion = true) + public async Task CompressDirectoryAsync(string directory, Stream archiveStream, string password, string searchPattern = "*", bool recursion = true) { - SaveContext(); - return Task.Run(() => new CompressDirectory2Delegate(CompressDirectory).Invoke(directory, archiveStream, password, searchPattern, recursion)) - .ContinueWith(_ => ReleaseContext()); + try + { + SaveContext(); + await Task.Run(() => new CompressDirectory2Delegate(CompressDirectory).Invoke(directory, archiveStream, password, searchPattern, recursion)); + } + finally + { + ReleaseContext(); + } } #endregion @@ -348,13 +408,19 @@ public void BeginCompressStream(Stream inStream, Stream outStream, string passwo /// The destination compressed stream. /// The archive password. /// ArgumentException: at least one of the specified streams is invalid. - public Task CompressStreamAsync(Stream inStream, Stream outStream, string password = "") + public async Task CompressStreamAsync(Stream inStream, Stream outStream, string password = "") { - SaveContext(); - return Task.Run(() => new CompressStreamDelegate(CompressStream).Invoke(inStream, outStream, password)) - .ContinueWith(_ => ReleaseContext()); - + try + { + SaveContext(); + await Task.Run(() => new CompressStreamDelegate(CompressStream).Invoke(inStream, outStream, password)); + } + finally + { + ReleaseContext(); + } } + #endregion #region BeginModifyArchive overloads @@ -382,11 +448,17 @@ public void BeginModifyArchive(string archiveName, IDictionary newF /// The archive file name. /// New file names. Null value to delete the corresponding index. /// The archive password. - public Task ModifyArchiveAsync(string archiveName, IDictionary newFileNames, string password = "") + public async Task ModifyArchiveAsync(string archiveName, IDictionary newFileNames, string password = "") { - SaveContext(); - return Task.Run(() => new ModifyArchiveDelegate(ModifyArchive).Invoke(archiveName, newFileNames, password)) - .ContinueWith(_ => ReleaseContext()); + try + { + SaveContext(); + await Task.Run(() => new ModifyArchiveDelegate(ModifyArchive).Invoke(archiveName, newFileNames, password)); + } + finally + { + ReleaseContext(); + } } #endregion diff --git a/SevenZip/SevenZipExtractorAsynchronous.cs b/SevenZip/SevenZipExtractorAsynchronous.cs index 2d07922..113cda0 100644 --- a/SevenZip/SevenZipExtractorAsynchronous.cs +++ b/SevenZip/SevenZipExtractorAsynchronous.cs @@ -112,11 +112,17 @@ public void BeginExtractArchive(string directory) /// Unpacks the whole archive asynchronously to the specified directory name at the specified priority. /// /// The directory where the files are to be unpacked. - public Task ExtractArchiveAsync(string directory) + public async Task ExtractArchiveAsync(string directory) { - SaveContext(); - return Task.Run(() => new ExtractArchiveDelegate(ExtractArchive).Invoke(directory)) - .ContinueWith(_ => ReleaseContext()); + try + { + SaveContext(); + await Task.Run(() => new ExtractArchiveDelegate(ExtractArchive).Invoke(directory)); + } + finally + { + ReleaseContext(); + } } /// @@ -136,11 +142,17 @@ public void BeginExtractFile(string fileName, Stream stream) /// /// The file full name in the archive file table. /// The stream where the file is to be unpacked. - public Task ExtractFileAsync(string fileName, Stream stream) + public async Task ExtractFileAsync(string fileName, Stream stream) { - SaveContext(); - return Task.Run(() => new ExtractFileByFileNameDelegate(ExtractFile).Invoke(fileName, stream)) - .ContinueWith(_ => ReleaseContext()); + try + { + SaveContext(); + await Task.Run(() => new ExtractFileByFileNameDelegate(ExtractFile).Invoke(fileName, stream)); + } + finally + { + ReleaseContext(); + } } /// @@ -160,11 +172,17 @@ public void BeginExtractFile(int index, Stream stream) /// /// Index in the archive file table. /// The stream where the file is to be unpacked. - public Task ExtractFileAsync(int index, Stream stream) + public async Task ExtractFileAsync(int index, Stream stream) { - SaveContext(); - return Task.Run(() => new ExtractFileByIndexDelegate(ExtractFile).Invoke(index, stream)) - .ContinueWith(_ => ReleaseContext()); + try + { + SaveContext(); + await Task.Run(() => new ExtractFileByIndexDelegate(ExtractFile).Invoke(index, stream)); + } + finally + { + ReleaseContext(); + } } /// @@ -184,11 +202,17 @@ public void BeginExtractFiles(string directory, params int[] indexes) /// /// indexes of the files in the archive file table. /// Directory where the files are to be unpacked. - public Task ExtractFilesAsync(string directory, params int[] indexes) + public async Task ExtractFilesAsync(string directory, params int[] indexes) { - SaveContext(); - return Task.Run(() => new ExtractFiles1Delegate(ExtractFiles).Invoke(directory, indexes)) - .ContinueWith(_ => ReleaseContext()); + try + { + SaveContext(); + await Task.Run(() => new ExtractFiles1Delegate(ExtractFiles).Invoke(directory, indexes)); + } + finally + { + ReleaseContext(); + } } /// @@ -208,11 +232,17 @@ public void BeginExtractFiles(string directory, params string[] fileNames) /// /// Full file names in the archive file table. /// Directory where the files are to be unpacked. - public Task ExtractFilesAsync(string directory, params string[] fileNames) + public async Task ExtractFilesAsync(string directory, params string[] fileNames) { - SaveContext(); - return Task.Run(() => new ExtractFiles2Delegate(ExtractFiles).Invoke(directory, fileNames)) - .ContinueWith(_ => ReleaseContext()); + try + { + SaveContext(); + await Task.Run(() => new ExtractFiles2Delegate(ExtractFiles).Invoke(directory, fileNames)); + } + finally + { + ReleaseContext(); + } } /// @@ -234,11 +264,17 @@ public void BeginExtractFiles(ExtractFileCallback extractFileCallback) /// 7-Zip (and any other solid) archives are NOT supported. /// /// The callback to call for each file in the archive. - public Task ExtractFilesAsync(ExtractFileCallback extractFileCallback) + public async Task ExtractFilesAsync(ExtractFileCallback extractFileCallback) { - SaveContext(); - return Task.Run(() => new ExtractFiles3Delegate(ExtractFiles).Invoke(extractFileCallback)) - .ContinueWith(_ => ReleaseContext()); + try + { + SaveContext(); + await Task.Run(() => new ExtractFiles3Delegate(ExtractFiles).Invoke(extractFileCallback)); + } + finally + { + ReleaseContext(); + } } } } diff --git a/SevenZip/SevenZipSfx.cs b/SevenZip/SevenZipSfx.cs index 78fcfd0..4526a78 100644 --- a/SevenZip/SevenZipSfx.cs +++ b/SevenZip/SevenZipSfx.cs @@ -1,5 +1,6 @@ namespace SevenZip { +#if SFX using System; using System.Collections.Generic; using System.Globalization; @@ -68,7 +69,6 @@ public class SevenZipSfx } } - private SfxModule _module = SfxModule.Default; private string _moduleFileName; private Dictionary> _sfxCommands; @@ -77,7 +77,7 @@ public class SevenZipSfx /// public SevenZipSfx() { - _module = SfxModule.Default; + SfxModule = SfxModule.Default; CommonInit(); } @@ -92,7 +92,7 @@ public SevenZipSfx(SfxModule module) throw new ArgumentException("You must specify the custom module executable.", nameof(module)); } - _module = module; + SfxModule = module; CommonInit(); } @@ -102,7 +102,7 @@ public SevenZipSfx(SfxModule module) /// public SevenZipSfx(string moduleFileName) { - _module = SfxModule.Custom; + SfxModule = SfxModule.Custom; ModuleFileName = moduleFileName; CommonInit(); } @@ -110,7 +110,7 @@ public SevenZipSfx(string moduleFileName) /// /// Gets the sfx module type. /// - public SfxModule SfxModule => _module; + public SfxModule SfxModule { get; private set; } /// /// Gets or sets the custom sfx module file name @@ -127,14 +127,14 @@ public string ModuleFileName } _moduleFileName = value; - _module = SfxModule.Custom; + SfxModule = SfxModule.Custom; var sfxName = Path.GetFileName(value); foreach (var mod in SfxSupportedModuleNames.Keys) { if (SfxSupportedModuleNames[mod].Contains(sfxName)) { - _module = mod; + SfxModule = mod; } } } @@ -178,7 +178,7 @@ private static SfxModule GetModuleByName(string name) /// The resource name for xml definitions private void LoadCommandsFromResource(string xmlDefinitions) { - using (Stream cfg = Assembly.GetExecutingAssembly().GetManifestResourceStream( + using (var cfg = Assembly.GetExecutingAssembly().GetManifestResourceStream( GetResourceString(xmlDefinitions + ".xml"))) { if (cfg == null) @@ -186,7 +186,7 @@ private void LoadCommandsFromResource(string xmlDefinitions) throw new SevenZipSfxValidationException("The configuration \"" + xmlDefinitions + "\" does not exist."); } - using (Stream schm = Assembly.GetExecutingAssembly().GetManifestResourceStream( + using (var schm = Assembly.GetExecutingAssembly().GetManifestResourceStream( GetResourceString(xmlDefinitions + ".xsd"))) { if (schm == null) @@ -195,18 +195,18 @@ private void LoadCommandsFromResource(string xmlDefinitions) "\" does not exist."); } var sc = new XmlSchemaSet(); - using (XmlReader scr = XmlReader.Create(schm)) + using (var scr = XmlReader.Create(schm)) { sc.Add(null, scr); var settings = new XmlReaderSettings {ValidationType = ValidationType.Schema, Schemas = sc}; - string validationErrors = ""; + var validationErrors = ""; settings.ValidationEventHandler += ((s, t) => { validationErrors += String.Format(CultureInfo.InvariantCulture, "[{0}]: {1}\n", t.Severity.ToString(), t.Message); }); - using (XmlReader rdr = XmlReader.Create(cfg, settings)) + using (var rdr = XmlReader.Create(cfg, settings)) { _sfxCommands = new Dictionary>(); rdr.Read(); @@ -218,7 +218,7 @@ private void LoadCommandsFromResource(string xmlDefinitions) rdr.Read(); do { - SfxModule mod = GetModuleByName(rdr["modules"]); + var mod = GetModuleByName(rdr["modules"]); rdr.ReadStartElement("config"); rdr.Read(); if (rdr.Name == "id") @@ -240,7 +240,7 @@ private void LoadCommandsFromResource(string xmlDefinitions) } } while (rdr.Name == "config"); } - if (!String.IsNullOrEmpty(validationErrors)) + if (!string.IsNullOrEmpty(validationErrors)) { throw new SevenZipSfxValidationException( "\n" + validationErrors.Substring(0, validationErrors.Length - 1)); @@ -257,30 +257,37 @@ private void LoadCommandsFromResource(string xmlDefinitions) /// The sfx settings dictionary to validate. private void ValidateSettings(SfxSettings settings) { - if (_module == SfxModule.Custom) + if (SfxModule == SfxModule.Custom) { return; } - List commands = _sfxCommands[_module]; + + var commands = _sfxCommands[SfxModule]; + if (commands == null) { return; } + var invalidCommands = new List(); - foreach (string command in settings.Keys) + + foreach (var command in settings.Keys) { if (!commands.Contains(command)) { invalidCommands.Add(command); } } + if (invalidCommands.Count > 0) { var invalidText = new StringBuilder("\nInvalid commands:\n"); - foreach (string str in invalidCommands) + + foreach (var str in invalidCommands) { invalidText.Append(str); } + throw new SevenZipSfxValidationException(invalidText.ToString()); } } @@ -293,23 +300,26 @@ private void ValidateSettings(SfxSettings settings) private static Stream GetSettingsStream(SfxSettings settings) { var ms = new MemoryStream(); - byte[] buf = Encoding.UTF8.GetBytes(@";!@Install@!UTF-8!" + '\n'); + var buf = Encoding.UTF8.GetBytes(@";!@Install@!UTF-8!" + '\n'); ms.Write(buf, 0, buf.Length); - foreach (string command in settings.Keys) + + foreach (var command in settings.Keys) { buf = Encoding.UTF8.GetBytes(String.Format(CultureInfo.InvariantCulture, "{0}=\"{1}\"\n", command, settings[command])); ms.Write(buf, 0, buf.Length); } + buf = Encoding.UTF8.GetBytes(@";!@InstallEnd@!"); ms.Write(buf, 0, buf.Length); + return ms; } private SfxSettings GetDefaultSettings() { - switch (_module) + switch (SfxModule) { default: return null; @@ -334,7 +344,7 @@ private SfxSettings GetDefaultSettings() /// Writes the whole to the other one. /// /// The source stream to read from. - /// The destination stream to wrie to. + /// The destination stream to write to. private static void WriteStream(Stream src, Stream dest) { if (src == null) @@ -350,6 +360,7 @@ private static void WriteStream(Stream src, Stream dest) src.Seek(0, SeekOrigin.Begin); var buf = new byte[32768]; int bytesRead; + while ((bytesRead = src.Read(buf, 0, buf.Length)) > 0) { dest.Write(buf, 0, bytesRead); @@ -408,12 +419,12 @@ public void MakeSfx(Stream archive, SfxSettings settings, Stream sfxStream) ValidateSettings(settings); - using (var sfx = Assembly.GetExecutingAssembly().GetManifestResourceStream(GetResourceString(SfxSupportedModuleNames[_module][0]))) + using (var sfx = Assembly.GetExecutingAssembly().GetManifestResourceStream(GetResourceString(SfxSupportedModuleNames[SfxModule][0]))) { WriteStream(sfx, sfxStream); } - if (_module == SfxModule.Custom || _sfxCommands[_module] != null) + if (SfxModule == SfxModule.Custom || _sfxCommands[SfxModule] != null) { using (var set = GetSettingsStream(settings)) { @@ -490,4 +501,5 @@ public void MakeSfx(string archiveFileName, SfxSettings settings, Stream sfxStre } } } +#endif } \ No newline at end of file diff --git a/appveyor.yml b/appveyor.yml index 7151937..e936628 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,7 +1,17 @@ -version: '1.4.0.{build}' +version: '1.5.0.{build}' image: Visual Studio 2019 -configuration: Release +environment: + COVERALLS_REPO_TOKEN: + secure: c5HtM5NVjJZQ4gbujqELYPgeCHTr9UMpuYl/A4MYX0lSdsMh/QISCfZxUHuLszPI + + matrix: + + - job_name: Regular Build + configuration: Release + + - job_name: Lite Build + configuration: LiteRelease dotnet_csproj: patch: true @@ -15,24 +25,35 @@ dotnet_csproj: before_build: nuget restore SevenZip.sln -environment: - COVERALLS_REPO_TOKEN: - secure: c5HtM5NVjJZQ4gbujqELYPgeCHTr9UMpuYl/A4MYX0lSdsMh/QISCfZxUHuLszPI - build: parallel: true project: 'SevenZip.sln' publish_nuget: false -after_build: - - cmd: nuget pack package.nuspec -version "%APPVEYOR_BUILD_VERSION%" +for: + + - + matrix: + only: + - job_name: Regular Build + + test_script: + - ps: Invoke-Expression ($env:USERPROFILE + '\.nuget\packages\OpenCover\4.7.922\tools\OpenCover.Console.exe -register:Path64 -filter:"+[*]* -[SevenZip.Tests]* -[nunit.framework]*" -target:"' + $env:USERPROFILE + '\.nuget\packages\nunit.consolerunner\3.10.0\tools\nunit3-console.exe" -targetargs:"/domain:single Stage/Release/net45/SevenZip.Tests.dll" -output:coverage.xml') + - ps: Invoke-Expression 'dotnet new tool-manifest' + - ps: Invoke-Expression 'dotnet tool install coveralls.net' + - ps: Invoke-Expression 'dotnet tool restore' + - ps: Invoke-Expression 'dotnet tool run csmacnz.Coveralls --opencover -i coverage.xml --repoToken $env:COVERALLS_REPO_TOKEN --useRelativePaths --commitId $env:APPVEYOR_REPO_COMMIT --commitBranch $env:APPVEYOR_REPO_BRANCH --commitAuthor $env:APPVEYOR_REPO_COMMIT_AUTHOR --commitEmail $env:APPVEYOR_REPO_COMMIT_AUTHOR_EMAIL --commitMessage $env:APPVEYOR_REPO_COMMIT_MESSAGE --jobId $env:APPVEYOR_BUILD_NUMBER --serviceName appveyor' + + after_build: + - cmd: nuget pack package.regular.nuspec -version "%APPVEYOR_BUILD_VERSION%" + + - + matrix: + only: + - job_name: Lite Build -test_script: -- ps: Invoke-Expression ($env:USERPROFILE + '\.nuget\packages\OpenCover\4.7.922\tools\OpenCover.Console.exe -register:Path64 -filter:"+[*]* -[SevenZip.Tests]* -[nunit.framework]*" -target:"' + $env:USERPROFILE + '\.nuget\packages\nunit.consolerunner\3.10.0\tools\nunit3-console.exe" -targetargs:"/domain:single Stage/Release/net45/SevenZip.Tests.dll" -output:coverage.xml') -- ps: Invoke-Expression 'dotnet new tool-manifest' -- ps: Invoke-Expression 'dotnet tool install coveralls.net' -- ps: Invoke-Expression 'dotnet tool restore' -- ps: Invoke-Expression 'dotnet tool run csmacnz.Coveralls --opencover -i coverage.xml --repoToken $env:COVERALLS_REPO_TOKEN --useRelativePaths --commitId $env:APPVEYOR_REPO_COMMIT --commitBranch $env:APPVEYOR_REPO_BRANCH --commitAuthor $env:APPVEYOR_REPO_COMMIT_AUTHOR --commitEmail $env:APPVEYOR_REPO_COMMIT_AUTHOR_EMAIL --commitMessage $env:APPVEYOR_REPO_COMMIT_MESSAGE --jobId $env:APPVEYOR_BUILD_NUMBER --serviceName appveyor' + after_build: + - cmd: nuget pack package.lite.nuspec -version "%APPVEYOR_BUILD_VERSION%" artifacts: - path: 'Squid-Box.SevenZip*.nupkg' diff --git a/changelog.md b/changelog.md index cbd5f7b..d2c614d 100644 --- a/changelog.md +++ b/changelog.md @@ -1,6 +1,10 @@ # Changelog -## 1.4.0 (2021-04-XX) +## 1.5.0 (2021-05-xx) +- Added .NET 5.0 (Windows only) variant. +- Added separate NuGet (Lite) excluding creation of self-extracting archives. + +## 1.4.0 (2021-04-12) - Added a work-around to allow UWP apps to use SevenZipSharp in Release builds. - Fix issue limiting split archive volume size to 2GB. diff --git a/package.lite.nuspec b/package.lite.nuspec new file mode 100644 index 0000000..07c73dc --- /dev/null +++ b/package.lite.nuspec @@ -0,0 +1,39 @@ + + + + Squid-Box.SevenZipSharp.Lite + 1.0.0 + Joel Ahlgren + Managed 7-zip library written in C# that provides data extraction and compression (all 7-zip formats are supported). + Wraps 7z.dll or any compatible one and makes use of LZMA SDK. Excludes creation of self-extracting executables, reducing file size. + en-US + LGPL-3.0-only + https://github.com/squid-box/SevenZipSharp + 7z sevenzip sevenzipsharp 7-zip + + Added new NuGet package excluding self-extraction functionality (Squid-Box.SevenZipSharp.Lite). + Added .NET Core 3.1 target, to prepare for future fixes. + Fixed issue with custom compression parameters for multithreading. + Fixed issue with exception handling in asynchronous compression and extraction methods, thanks to GitHub user kikijiki. + + + + + + + + + + + + + + + + + + + + + + diff --git a/package.nuspec b/package.regular.nuspec similarity index 50% rename from package.nuspec rename to package.regular.nuspec index 17ce36f..fd06a4e 100644 --- a/package.nuspec +++ b/package.regular.nuspec @@ -2,17 +2,19 @@ Squid-Box.SevenZipSharp - 1.4.0 + 1.0.0 Joel Ahlgren - Managed 7-zip library written in C# (.NET 4.5 and .NET Standard 2.0) that provides data (self-)extraction and compression (all 7-zip formats are supported). - Wraps 7z.dll or any compatible one and makes use of LZMA SDK. + Managed 7-zip library written in C# that provides data (self-)extraction and compression (all 7-zip formats are supported). + Wraps 7z.dll or any compatible one and makes use of LZMA SDK, includes self-extraction functionality. en-US LGPL-3.0-only https://github.com/squid-box/SevenZipSharp 7z sevenzip sevenzipsharp 7-zip - Added a work-around to allow UWP apps to use SevenZipSharp in Release builds. - Fix issue limiting split archive volume size to 2GB. + Added new NuGet package excluding self-extraction functionality (Squid-Box.SevenZipSharp.Lite). + Added .NET Core 3.1 target, to prepare for future fixes. + Fixed issue with custom compression parameters for multithreading. + Fixed issue with exception handling in asynchronous compression and extraction methods, thanks to GitHub user kikijiki. @@ -20,11 +22,18 @@ + + + + + + + diff --git a/readme.md b/readme.md index 5d0a284..d48aca5 100644 --- a/readme.md +++ b/readme.md @@ -2,16 +2,16 @@ This is a fork from [tomap's fork](https://github.com/tomap/SevenZipSharp) of th ## Continuous Integration -| Branch | Appveyor | Coveralls | NuGet | -|-----------|----------|-----------|-------| -| master | [![Build status](https://ci.appveyor.com/api/projects/status/bgp7yh7f0fpamt95/branch/master?svg=true)](https://ci.appveyor.com/project/squid-box/sevenzipsharp/branch/master) | [![Coverage Status](https://coveralls.io/repos/github/squid-box/SevenZipSharp/badge.svg?branch=master)](https://coveralls.io/github/squid-box/SevenZipSharp?branch=master) | [![NuGet Badge](https://buildstats.info/nuget/Squid-Box.SevenZipSharp)](https://www.nuget.org/packages/Squid-Box.SevenZipSharp/) | +| Branch | Appveyor | Coveralls | NuGet | Lite NuGet | +|-----------|----------|-----------|-------|------------| +| master | [![Build status](https://ci.appveyor.com/api/projects/status/bgp7yh7f0fpamt95/branch/master?svg=true)](https://ci.appveyor.com/project/squid-box/sevenzipsharp/branch/master) | [![Coverage Status](https://coveralls.io/repos/github/squid-box/SevenZipSharp/badge.svg?branch=master)](https://coveralls.io/github/squid-box/SevenZipSharp?branch=master) | [![NuGet Badge](https://buildstats.info/nuget/Squid-Box.SevenZipSharp)](https://www.nuget.org/packages/Squid-Box.SevenZipSharp/) | [![NuGet Badge](https://buildstats.info/nuget/Squid-Box.SevenZipSharp.Lite)](https://www.nuget.org/packages/Squid-Box.SevenZipSharp.Lite/) | | dev | [![Build status](https://ci.appveyor.com/api/projects/status/bgp7yh7f0fpamt95/branch/dev?svg=true)](https://ci.appveyor.com/project/squid-box/sevenzipsharp/branch/dev) | [![Coverage Status](https://coveralls.io/repos/github/squid-box/SevenZipSharp/badge.svg?branch=dev)](https://coveralls.io/github/squid-box/SevenZipSharp?branch=dev) | ## Changes from original project As required by the GNU GPL 3.0 license, here's a rough list of what has changed since the original CodePlex project, including changes made in tomap's fork. -* Target .NET framework changed from 2.0 to both .NET 4.5 and .NET Standard 2.0 (ie. .NET Framework 4.5+, .Net Core 2.0+, Mono 5.4+, UWP 10.0.16299+, Unity 2018.1+). -* Produces a multi-framework NuGet package. +* Target .NET framework changed from 2.0 to .NET 4.5, .NET Core 3.1 and .NET Standard 2.0 (ie. .NET Framework 4.5+, .Net Core 2.0+, Mono 5.4+, UWP 10.0.16299+, Unity 2018.1+). +* Produces two multi-framework NuGet packages, one full-feature package and a `Lite` variant without SFX support (and significantly smaller size). * Continous Integration added, both building and deploying, and code test coverage. * Tests re-written to NUnit 3 test cases. * General code cleanup.