System.IO.Packaging library does not read standard windows zip files - c#

When reading a zip package using the System.IO.Packaging assembly, I have found that zip files created using the standard windows zip utility are unable to be read (the package parts (internal files) of the zip package show as not existing).
After doing some research it appears that this is because the System.IO.Packaging library adds a Content_Types.xml to the zip when it is created, which does not appear to be present in a standard windows compressed zip.
Example:
using (Package Zip = Package.Open(BundlePath, FileMode.Open))
{
Uri FileUri = PackUriHelper.CreatePartUri(new Uri("somefile.xml", UriKind.Relative));
if (!Zip.PartExists (FileUri )) //this fails even though the file exists in the zip
throw new ResourceException(String.Format("Zip {0} does not contain file", BundlePath));
...
Is there anyway to still use the packaging system provided by .NET to read standard zip files, or do they need to be created using the library.
Edit:
Adding this file (Content_Types.xml) manually, and zipping using the Windows compression utility, proves to be successful in allowing the package to read.
Thanks.

System.IO.Packaging isn't there to read zip files but packages. Use DotnetZip instead.

Unfortunately I believe you are correct there isn't a good way to get the System.IO.Packaging libraries to open up any file in a standard zip format that doesn't contain that [content_types].xml file.
I was working on this issue a few months back, and this is what I was trying to implement something that would inject this file before we just decided to initially generate all of our files from within .NET:
the format of the zip file is the following
(---file 1---)(---file 2---)...(---file x---)(table of contents)
Without a third party library you should be able to open up a zip file as a binary file, hop to the end and read that table of contents, add a [content_types].xml file at the end with the types/default extension info, adjust the table of contents entries, append it to the end of the file, and go. The problem I was running into when trying to implement this is there are various checksums on the file to verify that it hasn't been corrupted, I hadn't gotten them all by the time I needed to change directions on this.
I'm sure this is more info that you needed, but should you decide to implement your own solution hopefully this helps.

Related

How to modify file under .zip file at git Repository

I have one git repository where I have to modify one file under that zip folder.
I'm looking a way to modify file over repository only. I know below one options:
download zip file and make changes and push it back [this is not working because my zip file is 11 mb and administrator not allowing me to increase the size which is currently 10 mb from the project setting in devops]
Is there any other way I can follow and modify the zip file content.?
Thanks
Under the hood, git will compare multiple versions of files, work out the differences, then compress everything.
By storing a file that's already compressed you are preventing git from storing multiple similar versions efficiently.
If you need a zip file, create it in your build script, not your source code.

Create a cab without a folder

I am trying to create a cab file that composes of 3 files. I am using WiX dlls as recommended on another page. The problem I face is that I need the files compressed without creating a folder. When I use the below method and extract the files once again, the compressed files are now houses within a folder of the same name as the cab file.
Is it possible create the file without the folder?
Here is my code
CabInfo cab = new CabInfo(#"c:\cab\test.cab");
List<String> files = new List<string>();
files.Add(#"C:\cab\test.D");
files.Add(#"C:\cab\test.L");
files.Add(#"C:\cab\test.U");
cab.PackFiles(null, files, null);
extracted files
-test
-test.D
-test.L
-test.U
The problem comes from the program that extracts the .cab file. Nothing can be done at compression side.
If the decompressor is yours, it can be made to extract files directly. 7-Zip has the option to not create the folder too.
There is nothing in the format of an archive (.cab or anything else) that can prevent that folder creation.

Saving multiple files types into one file

I'm developing a 3D application in which the user may load multiple images, the 3D library I use has a function to export the whole scene as XAML, of course in XAML I only have the path to the images, so the file will only be valid on the machine in which it has been created, what I want to do is to save the XAML , change image(s) path inside the XAML to be relative to the XAML file path, save image(s) along the XAML in the same new file, like this the new file will always contain the XAML and the images. how to save multiple files types within the same file ? any other suggestions on the whole idea would be appreciated.
If you are using .NET 4.5, then you can programmatically save multiple files into a zip folder easily using the new ZipFile class.
First, you'll need to prepare your files into a new folder (Directory.CreateDirectory, File.Move) and then you can simply use the ZipFile.CreateFromDirectory Method (adapted from the linked page):
string filePathOfNewFolder = #"c:\example\start";
string zipFilePath = #"c:\example\result.zip";
ZipFile.CreateFromDirectory(filePathOfNewFolder, zipFilePath);
UPDATE >>>
For .NET 4, you might have to rely more on third party libraries. You can download the DotNetZip library from the DotNetZip - Zip and Unzip in C#, VB, any .NET language page on CodePlex. It also works fairly simply. Here is an example taken from the linked page:
using (ZipFile zip = new ZipFile())
{
// add this map file into the "images" directory in the zip archive
zip.AddFile("c:\\images\\personal\\7440-N49th.png", "images");
// add the report into a different directory in the archive
zip.AddFile("c:\\Reports\\2008-Regional-Sales-Report.pdf", "files");
zip.AddFile("ReadMe.txt");
zip.Save("MyZipFile.zip");
}
Store your XAML and other image files into one file (e.g. zip or cab).
When running your program, unzip relevant file into a temp folder so you can get the relevant path working.
Empty the temp folder afterwards if required.

How to zip all files in folder

I have a folder "D:\folder" and in this folder I have 10 files that I need to zip into a new archive "D:\folder.zip".
Currently I'm using ICSharpCode.SharpZipLib but this is not a mandatory requirement, so other solutions are acceptable.
The problem I'm facing is that when I try to execute the method FileStream fs = File.OpenRead(#"D:\folder") I get an error because of access to the specifided path.
How can I zip these files in a simple way?
DotNetZip is much easier to use than SharpZipLib, example of zipping all files in folder :
using (ZipFile zip = new ZipFile())
{
zip.AddDirectory(#"MyDocuments\ProjectX", "ProjectX");
zip.Save(zipFileToCreate);
}
This is a an example from this page :
http://dotnetzip.codeplex.com/wikipage?title=CS-Examples&referringTitle=Examples
I also agree with the suggestion of Antonio Bakula to use DotNetZip instead of SharpZipLib.
.NET 4.5 includes the new ZipArchive and ZipFile classes for manipulating .zip files. With this support what you are trying to do is accomplished by:
ZipFile.CreateFromDirectory(#"D:\Folder", #"Folder.zip");
As a side note the reason you get the error is because you're trying to open a directory instead of a file. The File.OpenRead is used to open a file for read, since you provide a directory, you get the error. If you want to enumerate the files or directories inside a specific folder you can instead use Directory.EnumerateFiles or Directory.EnumerateDirectories.

Unzipping on the fly in C#

I have built a console application that works okay when it references a .exe file from a Program Files, but my users may not have that .exe in their Program Files directory.
I would prefer to keep the package as a single .exe for simplicity, so I was wondering how I can combine the two .exe's into one package.
One thing I thought of is zipping the .exe from the Program Files directory to a temporary location, and I would store the binary data for the zip archive in my console applications source code. Is this the best way to do it or are there better methods?
Note I do not have the source code of the .exe I want to reference in my console application.
You can certainly store extra files in your .exe (or .dll) as embedded resources. Simply change the "build action" for the item in the project to "Embedded Resource". You can retrieve the contents of the file (which could be compressed, if you wished) by using the following:
System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("stream name")
You could extract the file onto disk to be able to reference it, or you could load it directly with one of the Assembly.Load() variants, so you wouldn't need to ever store it on disk.
Note that if you do choose to extract it and store it on disk, you'll need administrator permissions on Vista and Windows 7 (and properly administered XP) operating systems in order to save the file(s) to the Program Files directory.
You can use GZipStream to compress and decompress files in C#. For more complex compression, you can use other Zip libraries like SharpZipLib.
Take a look at this link: Embedding assemblies inside another assembly
Basically, ILMerge will do what you are asking.

Categories