.NETZ Help and Usage Examples
The .NETZ tool can be used to transparently compress .NET standalone EXE files and non-shared DLLs (with some limitations). For best results, download a version of .NETZ compiled for the version of .NET Framework that you are using.
.NETZ is a command-line tool. All examples below should be typed in a CMD window (or placed in a batch *.BAT file for your project, that can be run as a post-build step from within Visual Studio IDE). It is recommended to add the directory where netz.exe is found to the system path.
Please read the help carefully before spending any effort to extend .NETZ. It is very probably that .NETZ does already everything you want.
In the examples that follow, it is supposed that we need to compress an application app.exe, which may depend on several libraries: lib1.dll, lib2.dll and lib3.dll.
- Troubleshooting (-c, -w, -i, -v)
.NETZ is a command-line tool. To install, download the zip file and unzip it to a folder (e.g.: C:\netz\). To compress your application either run .NETZ using an absolute path from its install location, or add the .NET EXE folder to your Windows system path. For example if your appliation EXE named app.exe is in folder C:\My Project\bin\Release, and netz.exe (and all its other needed files) is in C:\netz\, then you could use:
In the rest of the examples, the paths are not shown.
NETZ does not replace any compiler switches. Raw .NET modules, or resources (image, text, multi-media, etc), can be embedded directly with compiler switches into a .NET application and accessed using ResourceManagers, so there is no need for .NETZ to handle these.^ top
Packing EXE files
To compress only app.exe use:
It will create a directory app.exe.netz with the packed application. The zip.dll coming with .NETZ must be copied into the same folder as the packed EXE for it to run properly!
In order to embed the default zip.dll into the packed EXE, add the -z option, so no external DLLs are required:
The output folder for a packed EXE is by default a sub-folder in the directory where the orginal input EXE file is found, and it is named the same as the EXE file name with '.netz' appended to it. If you want another output folder, use the -o option. The folder must be different that the folder where the original EXE is found (because the outputed EXE file name is same, and the original EXE is not overwritten).
Optionally, to add the .NETZ version information to the packed EXE, use additionally the -n option.
By default a [STAThread] application is generated. To generate a [MTAThread] application add -mta option to the command-line.
No ready-made unpack option is provided.^ top
Packing DLL Files
To compress all or some of the managed DLL files that a .NETZ packed application uses try:
The respective packed files lib1z.dll and lib2z.dll will be placed in the original DLL directories. Copy them as necessary to the packed app.exe folder. A BATCH file can help to automate the process. The original DLLs are not deleted to avoid any errors and because they are still needed by the uncompressed version.
If you have already packed app.exe then you can pack additional the DLL files:
Wildcards in the DLL file names are accepted:
DLLs packed with .NETZ can be used only with EXE files packed also with .NETZ.^ top
Creating a Single EXE File
Most people use .NETZ to combine the EXE and all its used .NET DLLs into a single file. To pack some or all of the managed DLL-s as resources in a single compressed standalone .NET EXE file use:
The lib1z.dll and lib2z.dll will now be packed inside the compressed app.exe as resources.
The -s option is valid only when an EXE file is specified. The names of the DLL files need not to be unique, but the DLL assemblies themselves must be unique. Embedded DLL files are identified (only) by their full assembly name. In practical terms, this means that resource DLLs for different cultures (DLLs with the same name, but under different culture subdirectories) can be safely embedded in the single EXE. Just specify the path to each resource DLL that you want to include.
You could also pack zip.dll (or any other custom compression provider redistributable DLL file) as part of the packed application by using the -z option.
If the single EXE file has no DLL compressed with .NETZ apart of the ones that are embedded with the -s option (and -z) and the -p option is not used, then you can use the -so option to remove the functionality of loading *z.dll files from the packed application. The -so option could save around 4KB of size.
or even if you have no DLLs at all:
Packing Dynamically Loaded Assemblies
By default, .NETZ uses the full assembly name of a DLL to pack it as a resource within the EXE file. This means that if your application dynamically loads assemblies, using code, such as:
Then .NETZ cannot find the packed lib2.dll.
To remedy this, you have the option to tell .NETZ to use the assembly file name when packing, by using the -d option (-d stands for dynamic) before all the assemblies that you load dynamically and want to pack with .NETZ. For example:
In this case .NETZ will not use the full assembly name (and will not mangle it) for the lib2.dll, and can find lib2 when you load it dynamically with code as above.
Wildcards cannot be used for DLLs files specified with -d option, and only file names without spaces are supported.
The -d option uses the DLL file name to name the packed resource. If you want another name you can specify it using ':' after the -d option, for example:
You can now use Assembly.Load("mydynamiclib") in your code to load lib2.dll. Only names without spaces are supported.
The -d option has also two special forms:
- -d:@ uses the full internal assembly name
- -d:# uses the short internal assembly name
To see the names used for packed resources use the -v option. It will report, among the other stuff, the resource IDs as RID: string after every packed file.
The resource names must be unique. The default naming schema of .NETZ ensures strong linking of DLLs, inluding the version and the culture information. The -d option skips this check. Do not change a DLL resource name with -d, unless you really need to.^ top
Handling Localized Resource DLLs
For .NET 1.0 and .NET 1.1, there is nothing special to do about locaized resource DLLs. Treat them as normal DLLs. For example, to pack the .NET SDK sample WorldCalc and its language resource DLLs use:
To test, run the packed worldcalc.exe:
The title of the window will be different in the two cases.
For more details see the:
.NET SDK \Samples\Tutorials\resourcesandlocalization\worldcalc
.NET 2.0 cannot be supported. The ResourceManager was rewritten for .NET 2.0 and it does not raise the AssemblyResolve and ResourceResolve events properly from the new code (it seems the programmer at all forgot about this). Instead, .NET2.0 looks by default into the main assembly only. Using [assembly: Neutral Resources Language Attribute( "en" , Ultimate Resource Fallback Location . Satellite )] attribute will throw a Missing Satellite Assembly Exception and after this point there is nothing that can done. You can help by writing an email to Microsoft .NET team asking to have this .NET 2.0 bug fixed.A workaround for .NET 2.0, suggested by A. Ripault, ar_world2005 [ at ] yahoo.fr, is to use the .NETZ -p option to specify a private directory path where you list the unpacked localization resource DLLs. The folder structure should look as follows:
This way you can pack all the other assemblies with .NETZ, and have a single subfolder for all unpacked resource DLLs.^ top