.NETZ Help and Usage Examples

Basics | Intermediate | Advanced | Troubleshooting

For a quick start read Packing EXE Files and Creating a Single EXE File (EXE+DLLs), to pack together DLLs and the main EXE file into a single executable.

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.

I. Basics

.NETZ Tool

.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:

C:>cd "C:\My Project\bin\Release"
C:\My Project\bin\Release>"C:\netz\netz.exe" app.exe

In the rest of the examples, the paths are not shown.

.NETZ has a lot of options, but most of the time you will need only few of them. For a quick start read Packing EXE Files and Creating a Single EXE File.

Usage: netz [-s] [-so] [exe file] [[-d] dll file]*
            [-a assemblyAttributes file]
            [-o outPutFolder]
            [-aw] [-p privatePath] [-i win32icon] [-n] [-c | -w] [-mta]
            [-pl platform] [-x86]
            ([-z] [-r compressLib] [-l redistributableCompressLib])
            ([-kf] [-kn] [-kd] | [-ka])
            [-sr] [-srp file]
            [-v] [-b] [-!]
            [-xr] name [[-d] dll file]*
            [-csc] string


 -s   single exe, pack dll-s as resources      |
 -so  optimize single exe (valid with -s only) |
 -a   assemblyAttributes file, custom EXE assembly attributes
      in the Visual Studio C# format
 -o   output folder, will be created if not exists,
      default exename.netz
 -aw  warn about unhandled EXE assembly attributes, default ignore
 -p   privatePath, optional private application domain path
 -i   win32icon, optional icon file
 -n   add version info to starter, default no info
 -c   console exe CUI, default is autodetect |
 -w   windows exe GUI, default is autodetect |
 -pl  supports /platform cross-compilation in 64 bit systems |
 -x86 shortcut for -pl x86                                   |
  -mta adds MTAThread attribute to main
 Compress options:

 -r   compressLib, compress provider dll, default defcomp.dll
 -z   pack redistributable compress DLL as resource, ignored if no
      redistributable compress DLL
 -l   redistributableCompressLib, name of the redistributable
      compress DLL, overwrites the one given by the provider

 Strong name (sign) options: (default no sign)

 -kf  keyFile, to use for signing the packed assembly |
 -kn  keyName, to use for signing the packed assembly |
 -kd  set delay sign true, default false              |
 -ka  get keyFile, keyName, delay sign, and algorithmId from EXE
      attributes. The -kf, -kn and -kd are ignored when ka is specified

 Service options:
 -sr  creates a basic NT service from the input exe and dll files |
 -srp file, parameters file for -sr option |

 Debug options:

 -b   batch mode, generates a batch file and source code
 -v   print stack trace if error
 -!   print internal version

 The -xr option:
 -xr  the -xr should be used alone to create external DLL resources

 Other options:
       -csc string passes the string to csc compiler

 Input files:
      At most one EXE file must be specified at [exe file].
      The DLL files can be specified alone or with wildcards.     |
 -d   If use before a DLL file, this option tells .NETZ that      |
      the next DLL will be loaded dynamically by the application. |

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:

netz app.exe

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:

netz -z app.exe

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).

netz -z app.exe -o c:\test

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.

See also: EXE Assembly Attributes | Compression | Remoting

^ top

Packing DLL Files

To compress all or some of the managed DLL files that a .NETZ packed application uses try:

netz app.exe lib1.dll lib2.dll

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:

netz lib3.dll

Wildcards in the DLL file names are accepted:

netz .\bin\lib*.dll

DLLs packed with .NETZ can be used only with EXE files packed also with .NETZ.

See also: Limitations | Remoting

^ 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:

netz -s app.exe lib1.dll lib2.dll

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.

netz -s -z app.exe lib1.dll -so

or even if you have no DLLs at all:

netz -s -z app.exe -so

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:

Assembly assembly = Assembly.Load("lib2");

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:

netz -s -z -so app.exe lib1.dll -d lib2.dll lib3.dll

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:

netz -s -z -so app.exe lib1.dll -d:mydynamiclib lib2.dll

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.

See also: Limitations | Packing DLL Files | Compression | Remoting

^ 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:

netz -z -s worldcalc.exe .\de\WorldCalc.Resources.Dll

To test, run the packed worldcalc.exe:

worldcalc.exe de-ch

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


Next: Intermediate >>