Tell me more ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

Yeah UPX is a good compressor but it doesn't work with .NET executables.

upx: SampleExecutable.exe: CantPackException: .NET files (win32/.net) are not yet supported

So is there a good alternative for UPX and also works with .NET? It's good if the alternative is free.

share|improve this question
BTW, I want to use it just for reducing file size. – Proton Aug 23 '11 at 16:17
Try : crinkler.net – David Freitas Sep 30 '11 at 13:04

migrated from stackoverflow.com Aug 24 '11 at 1:05

4 Answers

up vote 6 down vote accepted

Take a look at .NETZ. Its probably what are you looking for. And its open source.

share|improve this answer
Just trying it out... – Proton Aug 23 '11 at 16:47
It would be better if it used LZMA (7-Zip) or WinRAR but thanks :) I may edit the code for use of 7-zip. – Proton Aug 23 '11 at 16:50
.NETZ is good but I found .netshrink better because it uses LZMA and slightly starts faster but it's not free so i'm gonna use .NETZ instead. But if you want to check it out: pelock.com/products/netshrink The Original Exe - 4.5 Mb --- .NETZ - 1.6 Mb ---netshrink 900 kb --- 7zipped (Ultra Setting) - 750 kb – Proton Aug 23 '11 at 17:04
@Proton, nice. Thanks for reply. – kirmir Aug 23 '11 at 17:05
Just thought a little more and said why don't I make a launcher like program which decompresses 7-zip and runs the process or even load the assembly in memory? But again it was a good answer. – Proton Aug 23 '11 at 17:11

Made some work...

// Thanks for Visual C# Kicks Memory Launcher Sample
//
// Used 7zxa.dll (170 kb) which is very light version of the original 7z.dll (1.3 Mb)
// Still, it's a plus 450+ kb (32,64-bit 7zip Lib + SevenZipSharp Lib) 
// So don't use it if your exe is not really so big.
using System;
using System.IO;
using System.Reflection;
using SevenZip;

namespace MemoryLauncher
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            if (IntPtr.Size == 8)
            {
                string dizin = Environment.GetFolderPath(Environment.SpecialFolder.System) +  @"\7zxa.dll";
                ExtractResource("7z64.dll", dizin);
                SevenZip.SevenZipBase.SetLibraryPath(dizin);
            }
            else
            {
                string dizin = Environment.GetFolderPath(Environment.SpecialFolder.System) + @"\7zxa.dll";
                ExtractResource("7z.dll", dizin);
                SevenZip.SevenZipBase.SetLibraryPath(dizin);
            }
            RunInternal7z("MemoryLauncher.SomeSevenZip.7z");
            //RunInternal7z(Properties.Resources.SomeSevenZip);
        }
        private static void ExtractResource(byte[] resBuffer, string dizin)
        {
            BinaryWriter writer = new BinaryWriter(File.Open(dizin, FileMode.OpenOrCreate, FileAccess.Write));
            writer.Write(resBuffer);
            writer.Close();
        }

        private static void ExtractResource(string resName, string dizin)
        {
            //Get the current assembly
            Assembly assembly = Assembly.GetExecutingAssembly();

            //If you're using ILMerge assembly name will be different
            //So the resource won't be extracted
            //Dont' use this
            //
            //Get the assembly's root name
            //string rootName = assembly.GetName().Name;

            //Get the resource stream
            Stream resourceStream = assembly.GetManifestResourceStream(resName);

            //Read the raw bytes of the resource
            byte[] resourcesBuffer = new byte[resourceStream.Length];

            resourceStream.Read(resourcesBuffer, 0, resourcesBuffer.Length);
            resourceStream.Close();

            BinaryWriter writer = new BinaryWriter(File.Open(dizin, FileMode.OpenOrCreate, FileAccess.Write));
            writer.Write(resourcesBuffer);
            writer.Close();
        }

        private static void RunInternal7z(byte[] zipBuffer)
        {
            var zipStream = new MemoryStream();
            zipStream.Seek(0, 0);
            zipStream.Write(zipBuffer, 0, zipBuffer.Length);

            //Extract 7zip file and load it into the memory
            var _7z = new SevenZipExtractor(zipStream);
            var memStream = new MemoryStream();
            _7z.ExtractFile(0, memStream);
            zipStream.Close();

            //Read the raw bytes of the resource
            byte[] resourcesBuffer = new byte[memStream.Length];

            memStream.Seek(0, 0); //Really needed//
            memStream.Read(resourcesBuffer, 0, resourcesBuffer.Length);
            memStream.Close();

            //Load the bytes as an assembly
            Assembly exeAssembly = Assembly.Load(resourcesBuffer);

            //Execute the assembly
            exeAssembly.EntryPoint.Invoke(null, null); //no parameters
        }

        private static void RunInternal7z(string zipName)
        {
            //Get the current assembly
            Assembly assembly = Assembly.GetExecutingAssembly();

            //If you're using ILMerge assembly name will be different
            //So the resource won't be extracted
            //Dont' use this
            //
            //Get the assembly's root name
            //string rootName = assembly.GetName().Name;

            //Get the resource stream
            Stream resourceStream = assembly.GetManifestResourceStream(zipName);

            //Extract 7zip file and load it into the memory
            var _7z = new SevenZipExtractor(resourceStream);
            var memStream = new MemoryStream();
            _7z.ExtractFile(0, memStream);

            //Read the raw bytes of the resource
            byte[] resourcesBuffer = new byte[memStream.Length];

            memStream.Seek(0, 0); //Really needed//
            memStream.Read(resourcesBuffer, 0, resourcesBuffer.Length);
            memStream.Close();

            //Load the bytes as an assembly
            Assembly exeAssembly = Assembly.Load(resourcesBuffer);

            //Execute the assembly
            exeAssembly.EntryPoint.Invoke(null, null); //no parameters
        }
    }
}
share|improve this answer
It's not an answer by the way... – PythEch Aug 24 '11 at 7:18
but +1 for interesting code :) – kirmir Aug 24 '11 at 8:57
1  
Thanks :) Also it can be done with 7zr.exe by extracting some files to Temp but it will be buggy and needs a lot of Exception handling. It doesn't worth for 200-300 kb. – PythEch Aug 24 '11 at 9:18
1  
By the way, added resources must be set Embedded Resource on Design Mode Properties > Build Action. – PythEch Aug 24 '11 at 9:24

I actually found MPRESS very good. I think I'm going to use this instead of .NETZ and above.

share|improve this answer

There are a number of compressors for .NET executables around you could try my one RPX it does not require any additional libraries for decompression but only adds about 7kb overhead so it does good compression even on small executables and can bundle multiple DLL(s) into a single .EXE file.

However there are some limitations caused by the manner, or more precisely the order, by which .NET looks for additional assemblies to load and where from (i.e 1. GAC, 2. File system, 3. Bundle) and is complicated more if you are using AppDomains inside your application.

Check the docs for more details. Hope that helps.

Please note: This is my project and as such this answer should not be seen as an endorsement from a third party. That said I do use it regularly, it is open source and it is my hope that others may benefit from it.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.