From 4f33dfda0343f8b55dca2f91d2bef6242a6a315b Mon Sep 17 00:00:00 2001 From: "andrey.shirokov" Date: Wed, 20 May 2020 16:53:48 +0300 Subject: [PATCH 1/8] do not dispose external stream --- SevenZip/ArchiveEmulationStreamProxy.cs | 11 ++++++++--- SevenZip/SevenZipExtractor.cs | 4 ++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/SevenZip/ArchiveEmulationStreamProxy.cs b/SevenZip/ArchiveEmulationStreamProxy.cs index 7a9481e..74757b2 100644 --- a/SevenZip/ArchiveEmulationStreamProxy.cs +++ b/SevenZip/ArchiveEmulationStreamProxy.cs @@ -18,16 +18,19 @@ internal class ArchiveEmulationStreamProxy : Stream, IDisposable /// public Stream Source { get; } + bool _dispose = true; /// /// Initializes a new instance of the ArchiveEmulationStream class. /// /// The stream to wrap. /// The stream offset. - public ArchiveEmulationStreamProxy(Stream stream, int offset) + /// Dispose wraped stream + public ArchiveEmulationStreamProxy(Stream stream, int offset, bool dispose = true) { Source = stream; Offset = offset; Source.Position = offset; + _dispose = dispose; } public override bool CanRead => Source.CanRead; @@ -72,12 +75,14 @@ public override void Write(byte[] buffer, int offset, int count) public new void Dispose() { - Source.Dispose(); + if(_dispose) + Source.Dispose(); } public override void Close() { - Source.Close(); + if(_dispose) + Source.Close(); } } } diff --git a/SevenZip/SevenZipExtractor.cs b/SevenZip/SevenZipExtractor.cs index 41d4a8b..ea311d6 100644 --- a/SevenZip/SevenZipExtractor.cs +++ b/SevenZip/SevenZipExtractor.cs @@ -107,7 +107,7 @@ private void Init(Stream stream) SevenZipLibraryManager.LoadLibrary(this, _format); try { - _inStream = new ArchiveEmulationStreamProxy(stream, _offset); + _inStream = new ArchiveEmulationStreamProxy(stream, _offset, false); _packedSize = stream.Length; _archive = SevenZipLibraryManager.InArchive(_format, this); } @@ -124,7 +124,7 @@ private void Init(Stream stream) _format = InArchiveFormat.PE; try { - _inStream = new ArchiveEmulationStreamProxy(stream, _offset); + _inStream = new ArchiveEmulationStreamProxy(stream, _offset, false); _packedSize = stream.Length; _archive = SevenZipLibraryManager.InArchive(_format, this); } From 53f0f8f4e35fa4ffa1d45a6fb9b74ad015355648 Mon Sep 17 00:00:00 2001 From: "andrey.shirokov" Date: Wed, 20 May 2020 16:55:00 +0300 Subject: [PATCH 2/8] fix perfomance degradation at GetUniqueID() --- SevenZip/SevenZipBase.cs | 31 ++++--------------------------- 1 file changed, 4 insertions(+), 27 deletions(-) diff --git a/SevenZip/SevenZipBase.cs b/SevenZip/SevenZipBase.cs index 87acae5..bd57ff2 100644 --- a/SevenZip/SevenZipBase.cs +++ b/SevenZip/SevenZipBase.cs @@ -15,7 +15,8 @@ public abstract class SevenZipBase : MarshalByRefObject { private readonly bool _reportErrors; private readonly int _uniqueID; - private static readonly List Identifiers = new List(); + private static readonly object _sync_uniqueIds = new object(); + private static int _lastUniqueId = int.MinValue; /// /// True if the instance of the class needs to be recreated in new thread context; otherwise, false. @@ -103,21 +104,9 @@ internal virtual void ReleaseContext() private static int GetUniqueID() { - lock (Identifiers) + lock (_sync_uniqueIds) { - int id; - - var rnd = new Random(DateTime.Now.Millisecond); - - do - { - id = rnd.Next(int.MaxValue); - } - while (Identifiers.Contains(id)); - - Identifiers.Add(id); - - return id; + return _lastUniqueId++; } } @@ -132,18 +121,6 @@ protected SevenZipBase(string password = "") _uniqueID = GetUniqueID(); } - /// - /// Removes the UniqueID from the list. - /// - ~SevenZipBase() - { - // This lock probably isn't necessary but just in case... - lock (Identifiers) - { - Identifiers.Remove(_uniqueID); - } - } - /// /// Gets or sets the archive password /// From f848b4b45b6c2db3e0db7c84f947c2040745ce06 Mon Sep 17 00:00:00 2001 From: "andrey.shirokov" Date: Wed, 20 May 2020 17:33:09 +0300 Subject: [PATCH 3/8] add target for net462 --- SevenZip.Tests/SevenZip.Tests.csproj | 2 +- SevenZip/SevenZip.csproj | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/SevenZip.Tests/SevenZip.Tests.csproj b/SevenZip.Tests/SevenZip.Tests.csproj index 1182036..31b1db4 100644 --- a/SevenZip.Tests/SevenZip.Tests.csproj +++ b/SevenZip.Tests/SevenZip.Tests.csproj @@ -1,6 +1,6 @@  - netstandard2.0;net45 + netstandard2.0;net45;net462 SevenZip.Tests SevenZipzTests Copyright © 2018 diff --git a/SevenZip/SevenZip.csproj b/SevenZip/SevenZip.csproj index 0623e62..dcc61ef 100644 --- a/SevenZip/SevenZip.csproj +++ b/SevenZip/SevenZip.csproj @@ -2,7 +2,7 @@ 9.0.30729 SevenZipSharp - netstandard2.0;net45 + netstandard2.0;net45;net462 true SevenZip.snk @@ -94,5 +94,6 @@ C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Configuration\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Configuration.dll + \ No newline at end of file From 0f5909d088f8cb6da11fc1f614febede387b94c3 Mon Sep 17 00:00:00 2001 From: "andrey.shirokov" Date: Wed, 20 May 2020 17:46:51 +0300 Subject: [PATCH 4/8] add target for net462 --- package.nuspec | 2 ++ 1 file changed, 2 insertions(+) diff --git a/package.nuspec b/package.nuspec index ec02133..b32128f 100644 --- a/package.nuspec +++ b/package.nuspec @@ -16,6 +16,7 @@ + @@ -25,6 +26,7 @@ + From 0f4772244ca4b7dfafad47453ee0772aa3dbacc3 Mon Sep 17 00:00:00 2001 From: "andrey.shirokov" Date: Wed, 20 May 2020 19:34:04 +0300 Subject: [PATCH 5/8] after review --- SevenZip/ArchiveEmulationStreamProxy.cs | 12 ++++++------ SevenZip/SevenZipBase.cs | 4 ++-- SevenZip/SevenZipExtractor.cs | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/SevenZip/ArchiveEmulationStreamProxy.cs b/SevenZip/ArchiveEmulationStreamProxy.cs index 74757b2..a7f2ca6 100644 --- a/SevenZip/ArchiveEmulationStreamProxy.cs +++ b/SevenZip/ArchiveEmulationStreamProxy.cs @@ -18,19 +18,19 @@ internal class ArchiveEmulationStreamProxy : Stream, IDisposable /// public Stream Source { get; } - bool _dispose = true; + readonly bool _leaveOpen = false; /// /// Initializes a new instance of the ArchiveEmulationStream class. /// /// The stream to wrap. /// The stream offset. - /// Dispose wraped stream - public ArchiveEmulationStreamProxy(Stream stream, int offset, bool dispose = true) + /// true to leave the wraped stream open after the ArchiveEmulationStreamProxy object is disposed; otherwise, false. + public ArchiveEmulationStreamProxy(Stream stream, int offset, bool leaveOpen = false) { Source = stream; Offset = offset; Source.Position = offset; - _dispose = dispose; + _leaveOpen = leaveOpen; } public override bool CanRead => Source.CanRead; @@ -75,13 +75,13 @@ public override void Write(byte[] buffer, int offset, int count) public new void Dispose() { - if(_dispose) + if(_leaveOpen) Source.Dispose(); } public override void Close() { - if(_dispose) + if(_leaveOpen) Source.Close(); } } diff --git a/SevenZip/SevenZipBase.cs b/SevenZip/SevenZipBase.cs index bd57ff2..49bb796 100644 --- a/SevenZip/SevenZipBase.cs +++ b/SevenZip/SevenZipBase.cs @@ -15,7 +15,7 @@ public abstract class SevenZipBase : MarshalByRefObject { private readonly bool _reportErrors; private readonly int _uniqueID; - private static readonly object _sync_uniqueIds = new object(); + private static readonly object _syncUniqueIds = new object(); private static int _lastUniqueId = int.MinValue; /// @@ -104,7 +104,7 @@ internal virtual void ReleaseContext() private static int GetUniqueID() { - lock (_sync_uniqueIds) + lock (_syncUniqueIds) { return _lastUniqueId++; } diff --git a/SevenZip/SevenZipExtractor.cs b/SevenZip/SevenZipExtractor.cs index ea311d6..3561522 100644 --- a/SevenZip/SevenZipExtractor.cs +++ b/SevenZip/SevenZipExtractor.cs @@ -107,7 +107,7 @@ private void Init(Stream stream) SevenZipLibraryManager.LoadLibrary(this, _format); try { - _inStream = new ArchiveEmulationStreamProxy(stream, _offset, false); + _inStream = new ArchiveEmulationStreamProxy(stream, _offset, leaveOpen: true); _packedSize = stream.Length; _archive = SevenZipLibraryManager.InArchive(_format, this); } @@ -124,7 +124,7 @@ private void Init(Stream stream) _format = InArchiveFormat.PE; try { - _inStream = new ArchiveEmulationStreamProxy(stream, _offset, false); + _inStream = new ArchiveEmulationStreamProxy(stream, _offset, leaveOpen: true); _packedSize = stream.Length; _archive = SevenZipLibraryManager.InArchive(_format, this); } From 13776bac8b3e4b32b2514b58a724abf5ccbc375a Mon Sep 17 00:00:00 2001 From: "andrey.shirokov" Date: Wed, 20 May 2020 19:34:43 +0300 Subject: [PATCH 6/8] add support for very long paths at net462 --- SevenZip.Tests/SevenZipExtractorTests.cs | 7 ++++++- SevenZip/ArchiveExtractCallback.cs | 13 +++++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/SevenZip.Tests/SevenZipExtractorTests.cs b/SevenZip.Tests/SevenZipExtractorTests.cs index 043bcfa..4f849bb 100644 --- a/SevenZip.Tests/SevenZipExtractorTests.cs +++ b/SevenZip.Tests/SevenZipExtractorTests.cs @@ -174,8 +174,13 @@ public void ThreadedExtractionTest() public void ExtractArchiveWithLongPath() { using (var extractor = new SevenZipExtractor(@"TestData\long_path.7z")) - { + { +#if NET462 + var uncOutputDirectory = @"\\?\"+ Path.GetFullPath(OutputDirectory); + Assert.DoesNotThrow(() => extractor.ExtractArchive(uncOutputDirectory)); +#else Assert.Throws(() => extractor.ExtractArchive(OutputDirectory)); +#endif } } diff --git a/SevenZip/ArchiveExtractCallback.cs b/SevenZip/ArchiveExtractCallback.cs index 65ef2fd..2705292 100644 --- a/SevenZip/ArchiveExtractCallback.cs +++ b/SevenZip/ArchiveExtractCallback.cs @@ -564,6 +564,11 @@ private static void ValidateFileNameAndCreateDirectory(string fileName) /// private static string RemoveIllegalCharacters(string str, bool isDirectory = false) { +#if NET462 + var isUncPath = str.StartsWith(@"\\?\"); + if(isUncPath) + str = str.Substring(@"\\?\".Length); +#endif var splittedFileName = new List(str.Split(Path.DirectorySeparatorChar)); foreach (char chr in Path.GetInvalidFileNameChars()) @@ -592,8 +597,12 @@ private static string RemoveIllegalCharacters(string str, bool isDirectory = fal splittedFileName.RemoveAt(0); splittedFileName[0] = new string(Path.DirectorySeparatorChar, 2) + splittedFileName[0]; } - - return String.Join(new string(Path.DirectorySeparatorChar, 1), splittedFileName.ToArray()); + var result = String.Join(new string(Path.DirectorySeparatorChar, 1), splittedFileName.ToArray()); +#if NET462 + if (isUncPath) + result = @"\\?\" + result; +#endif + return result; } } #endif From 70217c7e6aef76c09c21cee43ce73f4ad50d00d9 Mon Sep 17 00:00:00 2001 From: "andrey.shirokov" Date: Wed, 20 May 2020 19:44:29 +0300 Subject: [PATCH 7/8] fix after renameing --- SevenZip/ArchiveEmulationStreamProxy.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SevenZip/ArchiveEmulationStreamProxy.cs b/SevenZip/ArchiveEmulationStreamProxy.cs index a7f2ca6..36d9cef 100644 --- a/SevenZip/ArchiveEmulationStreamProxy.cs +++ b/SevenZip/ArchiveEmulationStreamProxy.cs @@ -75,13 +75,13 @@ public override void Write(byte[] buffer, int offset, int count) public new void Dispose() { - if(_leaveOpen) + if(!_leaveOpen) Source.Dispose(); } public override void Close() { - if(_leaveOpen) + if(!_leaveOpen) Source.Close(); } } From 39fcf12c6771a014c29aa012dbf3447c92a407fc Mon Sep 17 00:00:00 2001 From: misthophoroi <> Date: Wed, 20 May 2020 21:38:48 +0300 Subject: [PATCH 8/8] add support to run tests by 'dotnet test' --- SevenZip.Tests/SevenZip.Tests.csproj | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/SevenZip.Tests/SevenZip.Tests.csproj b/SevenZip.Tests/SevenZip.Tests.csproj index 31b1db4..ed5893d 100644 --- a/SevenZip.Tests/SevenZip.Tests.csproj +++ b/SevenZip.Tests/SevenZip.Tests.csproj @@ -15,6 +15,11 @@ + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + +