|
|
 Prize winner in Competition
"Best C# article of June 2008"
Comments and Discussions
|
|
 |

|
Hi All,
I am writing an application to compress directories. Can somebody please give me a working sample of compressing directories using 7z. SevenZIp only. plzzzz
so far i have this :
List string subfiles = new List string(Directory.GetFiles(inFolder));
foreach (string file in subfiles)
{
Console.WriteLine(Files to Compress : + file);
add Files to list
}
AddToArchive(inFolder, splitIntoDir);
public void AddToArchive(string fileToBeZipped, string zipDestination)
{
DirectoryInfo Di = new DirectoryInfo(zipDestination);
StringBuilder sb_archiveFile = new StringBuilder(zipDestination + Path.DirectorySeparatorChar + Di.Name + @".7z");
string archiveFile = sb_archiveFile.ToString();
SevenZip.SevenZipCompressor compressor = new SevenZipCompressor();
Console.WriteLine("zip destination : " + Di.Name);
if (!File.Exists(fileToBeZipped))
{
Console.WriteLine("Appending {0} to Archive ", fileToBeZipped);
compressor.CompressionMode = SevenZip.CompressionMode.Append;
}
else
{
Console.WriteLine("Creating {0} at Destination {1}....", fileToBeZipped, archiveFile);//MAKE OUT FILE A CREATED FILE NEWLY ONE
Console.WriteLine("CREATING:: ");
compressor.CompressionMode = SevenZip.CompressionMode.Create;
}
compressor.CompressionLevel = CompressionLevel.Normal;
compressor.CompressionMethod = CompressionMethod.Lzma;
compressor.CompressionMode = CompressionMode.Append;
compressor.CompressDirectory(zipDestination, archiveFile);
// compressor.CompressStream(streamer, streamer2);
}
}
|
|
|
|
|
|

|
"COM-like" interfaces! This is one reason technologies like COM and .NET came about, to turn messy lone wolf C++ programmers like Pavlov into the conditioned dog. Of course Pavlov probably doesn't give a rat's ass about any particular platform, so is happy as a clam. What other creatures need mentioning? Mean uncle Ivan perhaps.
|
|
|
|
|

|
You said multithreading could be an issue. I needed a Stream implementation for reading and since the extractor uses callback instead of allow single block readings i have implemented a blocking thread that holds the extraction until i want to read-it. The Stream is read-only and i can't seek it back, that enough for me...
The problem is at a certain point the svchost simply hangs and my application fails without any exception, i have discarded any synchronization issues between the threads, is it possible the COM management in C# could be screwing things up?
|
|
|
|

|
Anyone implemented support for the compression? Would be very handy. Thanks.
|
|
|
|
|

|
Hi All.
I can extract ZIP or RAR files by this demo project, it works.
I must extract file.DAT (7zip shows, that this file archive is type: Z)
So I changed code line to:
IInArchive Archive = Format.CreateInArchive(SevenZipFormat.GetClassIdFromKnownFormat(KnownSevenZipFormat.Z));
When I try to list archived files from file.DAT, I got: 0.
The problem is:
Archive.GetProperty(I, ItemPropId.kpidPath, ref Name);
or
Console.WriteLine(Name.GetObject());
Unpacking file.DAT doesn't work too.
How can I unpack file.DAT ?
Please help.
TomekA
|
|
|
|

|
The decompression logic just worked, no changes needed. Thanks again.
|
|
|
|

|
Could you please post an example translation of IOutArchive and IArchiveUpdateCallback
I am having trouble figuring out what needs to go as arguments to some of the methods
|
|
|
|

|
I tried using attached code (many thanks), and figured out that it doesn't work for *.cab files.
When I call:
Format.CreateInArchive(SevenZipFormat.GetClassIdFromKnownFormat(KnownSevenZipFormat.Cab)
it fails at:
Archive.Open(ArchiveStream, ref lCheckPos, null)
I would really appreciate any help.
Also, in the KnownSevenZipFormat there is no line for self-extracted .exe, and .msi ?
7zip can open them, but how to do it in code?GG
/MCP, MCSD, MCDBA/
|
|
|
|

|
hi,..
im doing some task that convert c#.net into vb.net code ...so there having some method..like...
..........................................................
public class InStreamWrapper : StreamWrapper, ISequentialInStream, IInStream
{
public InStreamWrapper(Stream baseStream) : base(baseStream) { }
public uint Read(byte[] data, uint size)
{
return (uint)BaseStream.Read(data, 0, (int)size);
}
}
public interface IInStream
{
uint Read([Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] byte[] data,uint size);
void Seek(long offset,uint seekOrigin,IntPtr newPosition); // ref long newPosition
}
public interface ISequentialInStream
{
uint Read(
[Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] byte[] data,
uint size);
}
public class StreamWrapper : IDisposable
{
protected Stream BaseStream;
protected StreamWrapper(Stream baseStream)
{BaseStream = baseStream; }
public void Dispose()
{ BaseStream.Close(); }
public virtual void Seek(long offset, uint seekOrigin, IntPtr newPosition)
{
long Position = (uint)BaseStream.Seek(offset, (SeekOrigin)seekOrigin);
if (newPosition != IntPtr.Zero)
Marshal.WriteInt64(newPosition, Position);
}
}
..........................................................
convert into
..........................................................
Public Class InStreamWrapper
Inherits StreamWrapper
Implements ISequentialInStream
Implements IInStream
Public Sub New(ByVal baseStream As Stream)
MyBase.New(baseStream)
End Sub
Public Function Read(ByVal data As Byte(), ByVal size As UInteger) As UInteger Implements ISequentialInStream.Read, IInStream.Read
Return CUInt(BaseStream.Read(data, 0, CInt(size)))
End Function
Public Overridable Sub Seek(ByVal offset As Long, ByVal seekOrigin As UInteger, ByVal newPosition As IntPtr) Implements IInStream.Seek
Dim Position As Long
'Position = CUInt(BaseStream.Seek(offset, DirectCast(seekOrigin, SeekOrigin)))
Position = CUInt(BaseStream.Seek(offset, seekOrigin))
If newPosition <> IntPtr.Zero Then
Marshal.WriteInt64(newPosition, Position)
End If
End Sub
End Class
<ComImport(), Guid("23170F69-40C1-278A-0000-000300030000"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)> _
Public Interface IInStream
'Inherits ISequentialInStream
' <PreserveSig()> _
' Function Read(<Out(), MarshalAs(UnmanagedType.LPArray, SizeParamIndex:=1)> ByVal data As Byte(), ByVal size As UInteger, ByVal processedSize As IntPtr) As Integer
Function Read(<Out(), MarshalAs(UnmanagedType.LPArray, SizeParamIndex:=1)> ByVal data As Byte(), ByVal size As UInteger) As UInteger
<PreserveSig()> _
Sub Seek(ByVal offset As Long, ByVal seekOrigin As UInteger, ByVal newPosition As IntPtr)
' ref long newPosition
End Interface
<ComImport(), Guid("23170F69-40C1-278A-0000-000300010000"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)> _
Public Interface ISequentialInStream
' <PreserveSig()> _
' Function Read(<Out(), MarshalAs(UnmanagedType.LPArray, SizeParamIndex:=1)> ByVal data As Byte(), ByVal size As UInteger, ByVal processedSize As IntPtr) As Integer
Function Read(<Out(), MarshalAs(UnmanagedType.LPArray, SizeParamIndex:=1)> ByVal data As Byte(), ByVal size As UInteger) As UInteger
End Interface
Public Class StreamWrapper
Implements IDisposable
Protected BaseStream As Stream
Protected Sub New(ByVal baseStream__1 As Stream)
BaseStream = baseStream__1
End Sub
Public Sub Dispose() Implements IDisposable.Dispose
BaseStream.Close()
End Sub
Public Overridable Sub Seek(ByVal offset As Long, ByVal seekOrigin As UInteger, ByVal newPosition As IntPtr)
Dim Position As Long
'Position = CUInt(BaseStream.Seek(offset, DirectCast(seekOrigin, SeekOrigin)))
Position = CUInt(BaseStream.Seek(offset, seekOrigin))
If newPosition <> IntPtr.Zero Then
Marshal.WriteInt64(newPosition, Position)
End If
End Sub
End Class
..........................................................
but it does not work. can you help me convert C# code into vb code ?
thanks in advance....
|
|
|
|

|
I used SharpDevelop to convert it into VB. Was able to successfully compile it in VB2010. However, getting "Not enough memory to complete the operation" error... But I just started...
|
|
|
|
|

|
This is spam. How does it relate to this article? Do you provide source code or library, that supports many formats? NO! So shut up and leave.
|
|
|
|

|
I think you are really not tried Sharp IMG Viewer and are not interested in LZMA decoding. I developed a managed library which supports MS-CAB, 7-ZIP formats.
|
|
|
|

|
Did you remove the demo from the zip file? I can't find it anywhere.
Thanks!
|
|
|
|

|
Hello,
First, I'd like to say thanks, I work with this interface for extracting ZIP and Z files and it works great.
The thing is, I now have to support TGZ files as well, but can't figure out the way to do it.
I use GZIP as the archive zip format (tried all others as well), but no luck...
Anyone tried it?
Thanks.
|
|
|
|

|
Do you mean any specific errors? Note that TGZ is a double archive - first data is packed with tar, second with GZIP, which means to extract GZIP and then Tar.
|
|
|
|

|
Hi, thanks for your reply.
I know about the GZIP and TAR.
I used your sample application, changed this line:
IInArchive Archive = Format.CreateInArchive(SevenZipFormat.GetClassIdFromKnownFormat(KnownSevenZipFormat.GZip));
and used this cmd: "e C:\Temp\Zipped\tgz1.tgz 1"
No errors really, just extraction produces nothing.
FileName argument is set to null after these lines:
PropVariant Name = new PropVariant();
Archive.GetProperty(FileNumber, ItemPropId.kpidPath, ref Name);
string FileName = (string)Name.GetObject();
|
|
|
|

|
You can also try ItemPropId.kpidName to get name. But in simple archive formats like bzip, z and partially gzip, file name is not stored inside archive, so you must reconstruct stored name from the archive name itself (in your case tgz1.tgz => tgz1.tar).
Liberavi animam meam!
|
|
|
|

|
Thank you for your replies.
Still, no luck.
Is there a chance anyone posts a sample code for extracting a simple TGZ file?
Thank you.
|
|
|
|

|
Well,
using (SevenZipExtractor extr = new SevenZipExtractor("your tgz archive path"))
{
extr.ExtractFiles("tar path", 0);
}
using (SevenZipExtractor extr = new SevenZipExtractor("tar path"))
{
extr.ExtractArchive("directory");
}
You must have SevenZipSharp though
|
|
|
|

|
I would be glad to your test results and hints.
|
|
|
|

|
Hi,
Could someone give me a hint or provide a sample code showing how a password protected archive can be extracted using this library?
Thanks
-- edit --
I found the solution. ICrypto... interface need to be implemented inside ArchiveExtractCallback class. I was doing it exactly the same and it didn't work. Finally found I got another bug which prevented me to decompress.
modified on Wednesday, February 18, 2009 2:18 PM
|
|
|
|

|
could you please link me to the code you used to implement password protected compression? It has been 3 years since you post this message I hope you have solved the issue.... Let me know how you did that... If possible please build step-by-step tutorial to use open source 7zip.DLL in VC++ 2010 MFC Application.... Thank you...
|
|
|
|

|
Hello!
First, thanks for that piece of work, it was very helpful! I am using the 2.0 version from the nomad homepage.
I understand basic extracting and creation of archive, that works wonderful. But now I am trying to do two things, which i just do not know how to do correctly:
1.) "Store" files in archive, so that they are not compressed, while creating a ZIP Archive
2.) Encrypt the files with a password
As far as i understand, both things are possible using the ISetProperties. I looked into the 7zip source code, and as far as i could understand, there input of this is an array of names, and array of propvalues, and a count.
The current ISetProperties takes as second parameter an IntPtr - and i do not know how to convert that to an array. I tried to change it to an array of AsAny, which does not work either (Exception when you call the function), and then i tried an Array of I4. This would call, but do nothing.
My call was something like this:
(outArchive as ISetProperties).SetProperties(new string[]{"x"}, new int[]{0},1);
But that does not change anything. Maybe I misunderstood the SetProperties as well. The 7z.exe call i wanted to simulate was "7za a -tZIP -mx=0 test.zip directorywithfiles".
Has someone done this already and could give me a hint?
Markus
|
|
|
|

|
Second parameter in ISetProperties.SetProperties is PropVariant array. You can use the following snippet to call it:
GCHandle ValuesHandle = GCHandle.Alloc(Values, GCHandleType.Pinned);
try
{
setProperties.SetProperties(Names, ValuesHandle.AddrOfPinnedObject(), Count);
}
finally
{
ValuesHandle.Free();
}
And don't forget that 7z.dll is very sensitive to variant type. And different format handlers have different set of available parameters.
For zip:
- Change compression method: m=Copy (Deflate, Deflate64, etc)
- Change encryption method: em=ZipCrypto (AES256)
Liberavi animam meam!
|
|
|
|

|
I made a sample *.7z archive (with LZMA compression) using the installed 7Zip tools, then I built your 7Zip interface library and copied 7z.dll from the installation folder into the project Debug output directory and ran the program.
I get these results:
C:\Documents and Settings\David\Desktop\Compression\7zIntf15\bin\Debug>SevenZip.exe e Files.7z 1
SevenZip
SevenZip l {ArchiveName}
SevenZip e {ArchiveName} {FileNumber}
Archive: Files.7z
Error: Insufficient memory to continue the execution of the program.
C:\Documents and Settings\David\Desktop\Compression\7zIntf15\bin\Debug>
Any idea?
|
|
|
|

|
Oh, silly me. I didn't change the line from this:
IInArchive Archive = Format.CreateInArchive(SevenZipFormat.GetClassIdFromKnownFormat(KnownSevenZipFormat.Zip));
to this:
IInArchive Archive = Format.CreateInArchive(SevenZipFormat.GetClassIdFromKnownFormat(KnownSevenZipFormat.SevenZip));
|
|
|
|

|
hi, how can I extract all the files in the 7zip file??
i tried to use the sample, but extract only the "0" file, I checekd a compressed file with 4 files, if I read the list, (using the l parameter in the sample ) reads correctly the 4 files, but when I extract, if I use 0 as filenumber extracts correctly the 0 file, but if I use 1 or any other filenumber ( in my case 0, 1, 2, 3 ) nothing will be extracted... the function archive.extract( ... returns 0 if is ok, and a negative number if fails...
does anybody help me?
thanks in advance!
|
|
|
|

|
I am using the version 2.0 from the authors homepage, but i did not experience that problem. I am using a "for" loop to extract all files, and this worked without problems. Could it be that you have an error in the filename you are extracting to? the source code in the sample did not include the folder to extract to, so the files would go the the programs current directory, whatever that is.
|
|
|
|

|
What value do I need to pass for 3rd argument?
|
|
|
|

|
It's the number of the file you wish to extract.
If you want to extract all, use 0xFFFFFFFF
|
|
|
|

|
Hi,
I am using c# wrapper of 7Zip.dll.
I want to recognize the file types of the provided archive as an input. Suppose if i wish to extract a zip file, i want to identify it through code that its type is zip. How could i do that in code.
Thanks.
Viram Pandey
|
|
|
|

|
You could do something like this:
private KnownSevenZipFormat GetArchiveFormat(string archivePath)
{
FileInfo archFile = new FileInfo(archivePath);
switch(archFile.Extension.ToUpper().Remove(archFile.Extension.IndexOf('.'), 1))
{
case "RAR":
return KnownSevenZipFormat.Rar;
case "ZIP":
return KnownSevenZipFormat.Zip;
case "7Z":
return KnownSevenZipFormat.SevenZip;
case "LZH":
return KnownSevenZipFormat.Lzh;
case "Z":
return KnownSevenZipFormat.Z;
case "LZMA":
return KnownSevenZipFormat.Lzma;
case "CBR":
return KnownSevenZipFormat.Rar;
case "CBZ":
return KnownSevenZipFormat.Zip;
default:
return KnownSevenZipFormat.Zip;
}
}
|
|
|
|

|
Hi,
I have one more problem in using c# wrapper of 7Zip.dll.
I need to specify my custom destination folder for the extracted files of archive.
Currently it decompresses all the files in the \bin\debug\ folder and i am not able to specify its custom destination path.
Thanks
Viram Pandey
|
|
|
|

|
Hi
I have the same problem as Viram regarding specifying the destination directory for unpacking operations(I don't know how to do it).
I wondered if any kind soul knows the answer?
Bertram
|
|
|
|

|
I went through the source code, but I still have no idea how to use it in my project(sorry, because I am a C# beginer). can somebody tell me how to use it? e.g. in the winform, I just need to specify a zip filename(.zip or .rar) and click a button, then the file can be decompression.
|
|
|
|

|
Hi
Does anyone have an example how to handle MultiVolume archives on extraction?
Thx for this great piece of code
|
|
|
|

|
It is relatively easy. Just implement IArchiveOpenVolumeCallback with IArchiveOpenCallback. 7z.dll will call GetProperty method with ItemPropId.kpidName, return archive name. Then 7z.dll calls GetStream method and give you archive name, you must provide stream for corresponding volume (or volumes, if there is several).
Liberavi animam meam!
|
|
|
|
|

|
The demo shows how to extract one file to the same directory as the executable ...
But what is the most efficient way of extracting all files in a 7zip archive to a single directory?
Greatly appreciate any help- and great work on this interface!
modified on Sunday, December 7, 2008 7:16 PM
|
|
|
|

|
Hello everyone. I have finished packing support, and even more, I've spent some time, and demo was updated with simple packing support, so you can find basic using principles of IOutArchive interface.
Sadly, but I did not found a way to update this article on CodeProject. And right now article is updated only on my site (http://dev.nomad-net.info/articles/sevenzipinterface[^]).
P.S. Sorry that update was taken so much time.
P.P.S. Article will be updated as soon as I find way to do this.
Liberavi animam meam!
|
|
|
|

|
Hi Eugene.
OK I now realise this is related to the 'solid' archive setting. My apologies - been staring at this so long, I missed the obvious! I will open a new thread.
Thanks for continuing to work on this.
I have the latest 7z.dll from the 7zip installation, and have read this forum & docs over and over again, but I still have one problem extracting:
if i pass this through cmd line, the file is extracted ok:
sevenzip.exe e "Dir\file.7z" 0
i.e. the 1st file extracts perfectly.
But if I try to extract another file (and I'm sure there's more than 1 in the archive), the app tells me the extraction is going ahead, but nothing happens.
If I comment out the code around line 220: if ((index == FileNumber) && (askExtractMode == AskMode.kExtract))...
... other files other than that the one at index 0 WILL extract, but seemingly it overwrites itself many times over (lots of 'filename kOK')
I was wondering if you'd encountered this and which 7z.dll version you've tested?
Many thanks again
modified on Sunday, December 7, 2008 6:11 PM
|
|
|
|

|
your site cannot be opened. can you send the demo with the source code to my email: linuxsuperfans@gmail.com?
|
|
|
|

|
I read this project serveral times , but I could not understand it.
that what this term means, and how to use it.I hope it and easier as another component---SharpZipLib.
there is my code to use zip, it is very simplely:
using ICSharpCode.SharpZipLib.Zip;
void myfunction(){
ZipFile zFile = new ZipFile(File.OpenRead(@"C:\mytest.zip"));
foreach (ZipEntry e in zFile) {
if (!e.IsFile) continue; Stream strm = zFile.GetInputStream(e);
MyWork_ReadData(strm);
strm.Close();
}
zFile.Close();
}
|
|
|
|

|
This translation is not intended to be easy to use. This is low-level 7z interfaces translation one to one. So this is foundation, you (or somebody else) can build easy-to-use archive framework on top of it. Actually, I have such framework, but right now it is tightly integrated with nomad.net, and it is very hard to cut it from there.
P.S. Of course some problems with article understanding comes from my language.
P.P.S. With SharpZipLib you have only zip support, and it lacks flexibility.
Liberavi animam meam!
|
|
|
|

|
ICSharpCode.SharpZipLib.Zip - very poor compration.
7-zip very easy:
CoderPropID[] propIDs =
{
CoderPropID.DictionarySize,
};
object[] properties =
{
(Int32)(23),
};
Stream inStream = new MemoryStream();
Stream outStream = new MemoryStream();
Stream Stream = new MemoryStream();
//...add data...//
inStream.Position = 0;
SevenZip.Compression.LZMA.Encoder encoder = new SevenZip.Compression.LZMA.Encoder();
SevenZip.Compression.LZMA.Decoder decoder = new SevenZip.Compression.LZMA.Decoder();
System.IO.MemoryStream prop = new System.IO.MemoryStream();
encoder.SetCoderProperties(propIDs, properties);
encoder.Code(inStream, outStream, -1, -1, null);
encoder.WriteCoderProperties(prop);
byte[] propArray = prop.ToArray();
decoder.SetDecoderProperties(propArray);
outStream.Seek(0, SeekOrigin.Begin);
decoder.Code(outStream, Stream, outStream.Length, inStream.Length, null);
|
|
|
|
 |
|
|
General News Suggestion Question Bug Answer Joke Rant Admin
Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.
|
Some interface translations for 7-Zip archive format DLLs.
| Type | Article |
| Licence | MIT |
| First Posted | 20 Jun 2008 |
| Views | 252,381 |
| Downloads | 8,012 |
| Bookmarked | 184 times |
|
|