I've been searching for a few days not to try and find why this is happening.
My WCF service is .net 4.0. I'm using sevinzipsharp as a wrapper for the 7zip libraries.
I have tried a number of things on both the client and server sides and found that the actual methods being used for the compression are not the issue. The issue is definitely related to the streaming process, because while debugging i can rout the server to the original compressed file rather than the streamed file and the archive is unpacked fine.
My reason for using compression at this point in time is to transfer multiple files in a package to my WCF service with a single call. If you can help me to resolve the issue I'm having with my current method or have a completely different suggestion as to how I can get multiple files to the server in the same call I would be very appreciative.
IService Code:
<ServiceContract()>
Public Interface IService
<OperationContract()>
Function start_Archive_Job(ByVal file_stream As Stream) As Boolean
IService Implementation:
Public Function start_Archive_Job(ByVal file_stream As Stream) As Boolean _
Implements DDSArchiveService.IService.start_Archive_Job
Dim f_zip As String = "C:\file_dest.7z"
//' define a buffer and bytes read var
Dim n As Integer
Dim buf(1024) As Byte
n = strm.Read(buf, 0, buf.Length)
If n = 0 Then Throw New File_Upload_Exception()
//' use a filestream to create the serverside file
Using fs As New FileStream(f_zip, FileMode.Create, FileAccess.Write, FileShare.None)
//' while the number of bytes read is not 0 and no exception occurrs continue to read from input and write to output
While n > 0
If Not n = buf.Length Then
Dim nbuf(n) As Byte
Array.Copy(buf, nbuf, n)
fs.Write(nbuf, 0, nbuf.Length)
Else
fs.Write(buf, 0, buf.Length)
End If
Try
n = strm.Read(buf, 0, buf.Length)
Catch ex As Exception
Exit While
End Try
End While
End Using
Dim decompressor As SevenZipExtractor
Try
//' check if 7zip is installed, if not look to the assemply location for the lib file
Dim dllPath As String
Dim sevenZ_reg As RegistryKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\7-zip")
If Not sevenZ_reg Is Nothing Then
dllPath = sevenZ_reg.GetValue("Path").ToString
Else
dllPath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location)
End If
SevenZipExtractor.SetLibraryPath(dllPath & "\7z.dll")
decompressor = New SevenZipExtractor(f_zip.7z)
decompressor.ExtractArchive(str_dsn_dir)
Catch ex As Exception
' write to log
Throw ex
End Try
The decompressor.ExtractArchive(str_dsn_dir)
call always seems to throw an exception that asks me if the file is encrypted and if the password is wrong, or tells me that the file may not have a signature that seven zip recognizes, so Tar was assumed.
The client code is:
Sub Main()
Dim binding As New System.ServiceModel.BasicHttpBinding()
binding.SendTimeout = New TimeSpan(0, 5, 0)
Dim webService As New ServiceReference1.ServiceClient(binding, New System.ServiceModel.EndpointAddress("myuri"))
Dim source As String = "C:\test_source"
Dim output As String = "C:\Zipped.7z"
Dim dllPath As String
//' check if 7zip is installed, if not look to the assemply location for the lib file
Dim sevenZ_reg As Microsoft.Win32.RegistryKey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("SOFTWARE\7-zip")
If Not sevenZ_reg Is Nothing Then
dllPath = sevenZ_reg.GetValue("Path").ToString
Else
dllPath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location)
End If
SevenZipExtractor.SetLibraryPath(dllPath & "\7z.dll")
Dim compressor As New SevenZipCompressor
compressor.ArchiveFormat = OutArchiveFormat.SevenZip
compressor.CompressionMode = CompressionMode.Create
compressor.CompressionMethod = CompressionMethod.Default
compressor.TempFolderPath = System.IO.Path.GetTempPath()
compressor.CompressDirectory(source, output)
Dim fs As New System.IO.FileStream(output, IO.FileMode.Open, IO.FileAccess.Read)
Try
webService.start_Archive_Job(fs)
fs.Dispose()
Catch ex As Exception
fs.Dispose()
End Try
End Sub
Again, help with this current issue, or ideas on how to package multiple files for a single call to a WCF web service into 1 stream and have them come out clean on the other end are acceptable and very appreciated.