This project is read-only.

Emebd DotNetZip into your application

Suppose you want to create an app, a WinForms app or command-line app. You like the features of DotNetZip, but you don't want to redistribute a DLL with your app; you want to redistribute the app as a single EXE. You looked at the options, and for whatever reason you do not want to use ILMerge. (One possible reason is that it is difficult to use ILMerge with signed assemblies, like DotNetZip. You need to strip the signature in order to use ILMerge).

An alternative to ILMerge is to simply add the DLL as an embedded resource into the exe itself, and then load the DLL from the embedded stream at runtime.

You'd add a reference to the DLL as normal. One key additional step is required: you must also physically add the DLL as an item in your project, with "Add Existing Item..." And you need to mark that item as "Embedded Content." The DLL itself will then become an embedded resource in your EXE. Then you add the following boilerplate code to your app: two static methods on your main class.

That's it. Easy peasy.

    // static constructor to add a handler to the AssemblyResolve event 
    static MainClass()  //   <--- this must be the name of your main class
    {
        AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(Resolver);
    }

    static System.Reflection.Assembly Resolver(object sender, ResolveEventArgs args)
    {
        Assembly a1 = Assembly.GetExecutingAssembly();
        Stream s = a1.GetManifestResourceStream("Ionic.Zip.dll");
        byte[] block = new byte[s.Length];
        s.Read(block, 0, block.Length);
        Assembly a2 = Assembly.Load(block);
        return a2;
    }

    ....




This technique works with any DLL of course. It is not specific to DotNetZip.

Last edited Nov 13, 2010 at 5:46 PM by Cheeso, version 6

Comments

Gilbou Jun 3, 2014 at 2:08 PM 
I have not been able to have this to work.
I have added the .dll as ressource, and on its properties set "Embedded ressource"
Then, I copied the supplied code. I have tried with prefixing and without with my namespace.

When run, program produces an exception : "Could not load file or assembly 'Ionic.zip, version=1.9.1.8"

I have tried :
Stream s = a1.GetManifestResourceStream("Générateur_de_Tranca.Ionic.Zip.dll");

namespace = Générateur_de_Tranca

TomT64 Jun 2, 2014 at 5:18 PM 
First of all, thank you very much for this code and examples. It seems to work wonderfully.

I just wanted to point out that the header text on this page is misspelled as "Emebd" so the authors can fix that. Please also feel free to delete this comment, as I do not wish to imply anything negative of the authors.

alecdee Nov 7, 2013 at 6:48 PM 
I'm confused as to where exaclty you add that code??

scim Mar 22, 2012 at 1:23 PM 
It does not seem to work with SaveSelfExtractor, it throws SfxGenerationException: "Errors compiling the extraction logic! Ionic.Zip-2012mar22-131826-76f0016c-f260-47b1-b3af-e634e5f2221f.cs"

Urutar Feb 21, 2012 at 11:00 AM 
Instead of using
Stream s = a1.GetManifestResourceStream("Ionic.Zip.dll");
(which returned null), you might want to use
Stream s = a1.GetManifestResourceStream(typeof(YourClassName), "Ionic.Zip.dll");
(where YourClassName is the name of your class).

tyrons Jan 21, 2012 at 1:02 PM 
And, as @bart_burkhardt noticed, it just worked to me once I've changed "Ionic.Zip.dll" to "MyNamespace.Ionic.Zip.dll"...

tyrons Jan 21, 2012 at 1:01 PM 
I'd change the comment "this must be the name of your main class" to "this must match the name of your main class", once there's no need to the main class be named "MainClass"...

RenanLazarotto Jan 2, 2011 at 5:48 PM 
This seems to be in C++. How can I do the same using VB.net?

bart_burkhardt Dec 6, 2010 at 1:47 PM 
It's working now,

It failed because I used the ZipFile code in the Main method.
After I moved the ZipFile using code in a Test function and called the Test function from the Main function it worked.
I also changed the Reference file properties, by default it will copy to the bin directory, it´s better not to do that because you will not use the file, and you want to make sure it loads from Resource.

bart_burkhardt Dec 4, 2010 at 11:13 AM 
I can't get this to work. I tried to create an console app to test this.
Although the embedding seems to work, it gives me an error that the file could not found.

I noticed that the ResourceStream name should be prepended with the name of the console app, in my case TestZip.Ionic.Zip.dll

So do you have a working example?, or a step by step howto to create this with an console app?