I generated a multi volume 7z file using SevenZipSharp library.
The problem I have is that when I try to extract the file, I get a exception about an invalid casting:
Unable to cast object
of type 'SevenZip.InMultiStreamWrapper' to type 'SevenZip.InStreamWrapper'.
The method that throws the exception is SevenZipExtractor.Check()
.
This is a sample code written in Vb.Net to reproduce the extraction problem, but I also can accept a C# solution:
Public Overridable Function Extract(ByVal sourceFilePath As String,
ByVal outputDirectorypath As String,
ByVal password As String) As String
If String.IsNullOrEmpty(password) Then
Me.extractor = New SevenZipExtractor(sourceFilePath)
Else
Me.extractor = New SevenZipExtractor(sourceFilePath, password)
End If
' Check for password matches doing an integrity check.
If Me.extractor.Check() Then
' Start the extraction.
Me.extractor.ExtractArchive(outputDirectorypath)
Else
Throw New Exception(
"Failed to extract, maybe the provided password does not match?.")
End If
Return outputDirectorypath
End Function
If I ignore the integrity check, with a multi volume file that has a password set, then I cannot extract it because another exception occurs...
Probablly is a bug in their source-code, but I ask to be sure, because it's very strange that the library does not support extracting multi volume files...
Probablly is a bug in their source-code
This is indeed the case.
Looking at the SevenZipExtractor.cs source code, we see the following line (inside the method finally
block, so it always executes):
((InStreamWrapper)_archiveStream).Dispose();
where the _archiveStream
is a class field of type IInStream
(note the I
) which is an interface type that does not derive from IDisposable
, hence has no Dispose
method.
Going deeper, we can see that it is initialized with instance of either InStreamWrapper
or InMultiStreamWrapper
class. While they both share common base class StreamWrapper
, the later does not inherit from the former, hence the cast exception.
Fixing it is quite easy if you are willing to modify the source code. Just replace the above line with:
if (_archiveStream is IDisposable)
((IDisposable)_archiveStream).Dispose();
However
If I ignore the integrity check, with a multi volume file that has a password set, then I cannot extract it because another exception occurs...
They do not call the Check
method internally, and there should not be any relation of whether you call Check
or not before calling ExtractArchive
. So I doubt that fixing the above bug will prevent the another exception you are talking about.