diff --git a/SevenZip.Tests/SevenZip.Tests.csproj b/SevenZip.Tests/SevenZip.Tests.csproj index 0e6ea4a..7736323 100644 --- a/SevenZip.Tests/SevenZip.Tests.csproj +++ b/SevenZip.Tests/SevenZip.Tests.csproj @@ -9,6 +9,7 @@ true SevenZipTests.snk Debug;Release;LiteDebug;LiteRelease + AnyCPU SFX diff --git a/SevenZip.Tests/SevenZipCompressorAsynchronousTests.cs b/SevenZip.Tests/SevenZipCompressorAsynchronousTests.cs index a162287..b0d831f 100644 --- a/SevenZip.Tests/SevenZipCompressorAsynchronousTests.cs +++ b/SevenZip.Tests/SevenZipCompressorAsynchronousTests.cs @@ -1,6 +1,8 @@ namespace SevenZip.Tests { + using System; using System.Collections.Generic; + using System.Diagnostics; using System.IO; using System.Threading; using System.Threading.Tasks; @@ -56,7 +58,7 @@ public void AsynchronousCompressFilesTest() { var compressionFinishedInvoked = false; - var compressor = new SevenZipCompressor {DirectoryStructure = false}; + var compressor = new SevenZipCompressor { DirectoryStructure = false }; compressor.CompressionFinished += (o, e) => compressionFinishedInvoked = true; compressor.BeginCompressFiles(TemporaryFile, @"TestData\zip.zip", @"TestData\tar.tar"); @@ -129,7 +131,7 @@ public void AsynchronousModifyArchiveTest() var compressionFinishedInvoked = false; compressor.CompressionFinished += (o, e) => compressionFinishedInvoked = true; - compressor.BeginModifyArchive(TemporaryFile, new Dictionary{{0, @"tartar"}}); + compressor.BeginModifyArchive(TemporaryFile, new Dictionary { { 0, @"tartar" } }); var timeToWait = 1000; while (!compressionFinishedInvoked) @@ -202,6 +204,24 @@ public async Task CompressFilesAsync() } } + [Test] + public void CompressFilesAsyncWithCancellationTest() + { + var compressor = new SevenZipCompressor { DirectoryStructure = false }; + compressor.Compressing += Compressor_Compressing; + var task = compressor.CompressFilesAsync(TemporaryFile, @"TestData\zip.zip", @"TestData\tar.tar"); + + Assert.ThrowsAsync(async () => { await task; }); + } + + private void Compressor_Compressing(object sender, ProgressEventArgs e) + { + if (e.PercentDone > 50) + { + e.Cancel = true; + } + } + [Test] public async Task CompressDirectoryAsync() { diff --git a/SevenZip/ArchiveUpdateCallback.cs b/SevenZip/ArchiveUpdateCallback.cs index cb127db..f52cd61 100644 --- a/SevenZip/ArchiveUpdateCallback.cs +++ b/SevenZip/ArchiveUpdateCallback.cs @@ -325,6 +325,7 @@ private void OnCompressing(ProgressEventArgs e) if (Compressing != null) { Compressing(this, e); + Canceled = e.Cancel; } } @@ -342,7 +343,12 @@ private void OnFileCompressionFinished(EventArgs e) public void SetTotal(ulong total) {} - public void SetCompleted(ref ulong completeValue) {} + public void SetCompleted(ref ulong completeValue) { + if (Canceled) + { + throw new SevenZipCompressionCanceledException(); + } + } public int GetUpdateItemInfo(uint index, ref int newData, ref int newProperties, ref uint indexInArchive) { diff --git a/SevenZip/EventArguments/ProgressEventArgs.cs b/SevenZip/EventArguments/ProgressEventArgs.cs index aa2b163..7fc1b8d 100644 --- a/SevenZip/EventArguments/ProgressEventArgs.cs +++ b/SevenZip/EventArguments/ProgressEventArgs.cs @@ -22,5 +22,9 @@ public ProgressEventArgs(byte percentDone, byte percentDelta) /// Gets the change in done work percentage. /// public byte PercentDelta => _delta; + /// + /// Allows you to cancel the compression operation. + /// + public bool Cancel { get; set; } = false; } } diff --git a/SevenZip/Exceptions/SevenZipCompressionCanceledException.cs b/SevenZip/Exceptions/SevenZipCompressionCanceledException.cs new file mode 100644 index 0000000..e4a3f88 --- /dev/null +++ b/SevenZip/Exceptions/SevenZipCompressionCanceledException.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace SevenZip +{ + /// + /// Exception thrown when compression is canceled. + /// + public class SevenZipCompressionCanceledException: Exception + { + /// + /// Message of exception. + /// + public override string Message => "Canceled"; + } +} diff --git a/SevenZip/SevenZipBase.cs b/SevenZip/SevenZipBase.cs index 540303e..2bbffe4 100644 --- a/SevenZip/SevenZipBase.cs +++ b/SevenZip/SevenZipBase.cs @@ -164,7 +164,14 @@ internal void ThrowUserException() { if (HasExceptions) { - throw new SevenZipException(SevenZipException.USER_EXCEPTION_MESSAGE); + if ((_exceptions.Count == 1) && (_exceptions[0] is SevenZipCompressionCanceledException)) + { + throw new SevenZipCompressionCanceledException(); + } + else + { + throw new SevenZipException(SevenZipException.USER_EXCEPTION_MESSAGE); + } } } @@ -178,6 +185,11 @@ internal void CheckedExecute(int hresult, string message, CallbackBase handler) { if (hresult != (int)OperationResult.Ok || handler.HasExceptions) { + if ((handler is ArchiveUpdateCallback) && (handler.Canceled) && (!handler.HasExceptions)) + { + AddException(new SevenZipCompressionCanceledException()); + return; + } if (!handler.HasExceptions) { if (hresult < -2000000000)