.NETZ Help and Usage Examples III
Platforms - 32bit, 64bit (-pl, -x86)
To cross-compile with .NETZ in a 64-bit platform use version of .NETZ compiled with .NET 2.0 and the -pl string option of .NETZ. The -pl option is equal to the /platform:string of the .NET CSC compiler. The string values passed to -pl are the same as the string values that are valid for the .NET CSC /platform:string compiler option: x86, x64, Itanium, and anycpu. Default is 'anycpu'. The -pl strings are passed directly to the .NET CSC compiler by using the /platform option. For example, to cross-compile for 32-bit in a 64-bit platform, append -pl x86 to the rest of .NETZ command-line options (valid only with .NET 2.0+).
netz -pl x86 -s -so -z app.exe l*.dll
The .NETZ -x86 option is provided as a shortcut for -pl x86.
.NETZ has been test with .NET 1.0, 1.1, and 2.0 in most Win32-bit platforms. The .NET 2.0 pre-compiled binary of .NETZ found in downloads will work ok in 64-bit systems (or you can try to compile the .NETZ source-code with the version of .NET Framework that you are using). The native 32-bit subsys.dll component of .NETZ can correctly parse both the 32-bit and the 64-bit CLR PE files.
^ top
The Batch Option (-b)
The -b option is useful to debug .NETZ starter code or, in general, to customize it. With the -b option, .NETZ will generate source code instead of compiling the starter application directly. A makefile.bat is generated to enable manually compiling the starter application. Append the -b option to all the other options that you use in your project with netz.exe. For example if your command-line is:
netz -s -so -z app.exe *.dll
Then use just add -b as follows:
netz -s -so -z -b app.exe *.dll
If you are using keyfiles (-kf) you may need to copy them explicitly to the folder generated by -b.
This option comes often handy when you are unsure what .NETZ does. Rather than looking at the .NETZ source code, you can look at the output generated code. While it is easy to customize the start code directly, this is not recommended for your final version. Modify the starter code on your own risk. Custom starter code is not supported. The start code may change in different version of .NETZ, and you will have to maintain it manually all the time. If you find problem, or want a customization that in not already available through the .NETZ command-line options, then please report it, and it will be very probably included as an option in the newer .NETZ version.
See also: EXE Assembly Attributes
^ top
Grouping DLLs in External Resources (-xr)
The -xr option enables packing a set of .NET DLLs used by the application, not inside a single EXE as the -s option does, but in a separate external resource file. The -xr should be used alone and as the first argument. For example, to pack the lib2.dll and lib3.dll with -xr use:
netz -xr test lib2.dll lib3.dll
Only the -r and -d options can be used with -xr (after -xr).
The -xr command above will create a file named test-netz.en-US.resources. The file name ending *-netz.en-US.resources cannot be changed. The .en-US.resources is required by default .NET resource manager and while it is possible to create a custom resource manager, it would add size to the packed EXEs. The "-netz" part of the name is used by .NETZ started to find such resource files.
Then you can pack app.exe with .NETZ as with any other application:
or if you have DLLs to embed use:
netz -s -z app.exe lib1.dll
The -s is required, and -so should not be used. After this you can distribute the packed app.exe and test-netz.en-US.resources. When the packed app.exe is run, it will find lib1.dll in its internal resources, but it will find lib2.dll and lib3.dll in the external test-netz.en-US.resources file.
You can create as many resource files as you like. The only requirement is that they should be placed in the same folder as app.exe. They are searched in alphabetic order, and before the internal resources (so you have a possibility to easily replace a previously embedded DLL).
The external resources are useful if you plan to distribute later on a new set of DLLs for an existing application. For example, if you have a new plugin1.dll that depends on lib2.dll and lib3.dll, you need only to distribute, plugin.dll (or the packed pluginz.dll) and plugin-netz.en-US.resources. The "en-US" in the external resource name is just a convention; the culture of packed DLLs does not matter. You can also pack all plugin.dll, lib2.dll and lib3.dll, in the same external resource file plugin-netz.en-US.resources, and use the names of external resource file to identify plugins.
^ top
GAC, Serialization, Remoting, and Unhandled .NET Assemblies
.NETZ tool has some limitations. This section gives details about a few of them:
- GAC, shared DLLs .NETZ can compress non-shared .NET DLL and assembly files (no native DLLs). That is, .NETZ can compress almost all .NET DLL files that are used by a single application and that are not placed in GAC. If a DLL, e.g., lib1.dll file is shared by more than one application, e.g., app1.exe and app2.exe, then you can still compress lib1.dll to lib1z.dll if you compress both app1.exe and app2.exe with the .NETZ tool (see also: limitations).
- Serialization, Remoting Some non-shared .NET assemblies, however, cannot be compressed by .NETZ. These assemblies are directly accessed by .NET CLR, or by .NET libraries. For example, applications that use .NET serialization or remoting (marshaling) are accessed by the built-in .NET serialization logic to generate the serialization code. During serialization the assembly information is added to the serialized data. During deserialization, a problem will show as the .NET will try to access the assembly directly to interpret the data (using Assembly.Load or Assembly.LoadWithPartialName). The details are different in different .NET versions. For example, the XML Serialization generates AssemblyResolveEvents in .NET 2.0, when an assembly is not found by the Load methods, but it does not generate such events in .NET 1.1 (reference). These applications will fail when compressed with .NETZ, and when run under .NET run-time versions lower than .NET 2.0 (Ludwig Stuyck (ludwig.stuyck [ at ] ctg.com) reported that serialization of generics in .NET 2.0 is still problematic with regard of this issue). .NETZ relies on the availability of the AssemblyResolveEvents to provide assemblies (for .NET 2.0, the serialization code will work fine with .NETZ, if placed in a separate packed DLL, but not inside an EXE file.). Because, serialization and marshalling are also used by the .NET remoting, the remoting applications could also fail.
There is a simple workaround that can be used in general for all these types of applications (e.g., serialization before .NET 2.0). You have to place all types shared by remoting (or in general needed directly by the .NET CLR) in a separate DLL file that is not compressed with .NETZ. You can then compress the rest of EXEs and DLLs with .NETZ. For example, suppose you have two applications server.exe and client.exe. The client.exe uses some form of .NET remoting to call access objects of server.exe (example). The definitions of all interfaces and types used by both the server, or the client application to connect to the server via .NET remoting should be placed in one or more separate DLL files, e.g. shared.dll. If you do not want to place too much code in the shared DLL file, use interfaces of types that contain only data, but not functionality.
See also: Limitations
^ top
Handling New / Different .NET Versions
.NETZ compiles the starter application using the default .NET version, under which the .NETZ is being run. There can be occasionally problems if the version of .NET run-time used by .NETZ does not mach the one used to compile the application, that is, when you have more than one .NET run-time installed.
-
If .NETZ uses a lower .NET run-time that the one used by the application, then the packed application will be linked against the lower version and in run-time types of the new .NET run-time may not be found. For example, this screenshot reported by a user, shows an error that has resulted from packing a NET 1.1 application that uses System.Windows.Forms.FolderBrowserDialog, against the .NET 1.0 ( with a .NETZ version compiled for .NET 1.0). This process is known as assembly unification.
To ease finding such bugs, .NETZ now reports properly the .NET run-time used to pack the application and the .NET run-time the application is running under, if such an error dialog is shown.
To see the current version of the .NET run-time, and the verson of .NET run-time used to compile .NETZ binary you are using, try the -! option. See also the .NET documentation on MSDN for details on how to configure the exact .NET run time by creating an .NET 1.0 style netz.exe.config XML file for netz.exe.
For best results, use a version of .NETZ compiled with the version .NET Framework that you are using.
The managed EXE or DLL assembly files could belong to newer, or different .NET versions. For example, the .NET 2.0 assemblies may not be parsed by a binary version of .NETZ compiled for .NET 1.0. In this case, the warning 1001 is issued. This warning usually means that there is a version mismatch between the .NET runtime used by .NETZ, and the one used to compile the input EXE or DLL files.
The solution for this problem is to recompile .NETZ source code with the version of .NET that you are using (or download a ready compiled .NETZ version for your version of the .NET run-time). See: Compiling .NETZ.
Because of the non-compatible resource managers in different versions of .NET, the string resources used
by .NETZ and the .NETZ compression providers must be carefully created. The .NETZ embedded resources must also match the .NET version used. The solution for this problem is to properly recompile .NETZ source code with the version of .NET that you are using (or download a ready compiled .NETZ version for your version of the .NET run-time). See: Compiling .NETZ.
To get more details about a .NETZ error, or warning use the -v option.
^ top
Compiling .NETZ
.NETZ compilation is made simple to easy handle new / different .NET versions. To recompile .NETZ for a given .NET version, you need to have the corresponding .NET SDK. No Visual Studio is needed. Even if you have Visual Studio, use the build.bat file that comes with the .NETZ source code to properly compile .NETZ.
To recompile .NETZ follow these steps:
- Download the latest source code from this web site and unzip it in a folder.
- Open a .NET SDK command-line window (with .NET environment variables properly set) and go (using CD) to the unzipped folder of .NETZ, where the .NETZ source code is found.
- Type csc and Enter in the command-line to verify the version of the C# compiler and the .NET run-time that you are using.
- Then, run the build.bat file from within the directory where it is found. The .NETZ compiled binaries will be placed in a new folder named netz-bin. Ignore any compiler errors / warnings shown during the build, as .NETZ contains code that targets different .NET versions.
- Note on resources: During the .NETZ build process,
the .NETZ resource creator tool (makeres.exe) is
also recompiled with the current .NET version used.
Furthermore, a small tool called setdotnetver.exe is
called to hardwire the .NET version that
makeres.exe uses. If you need to specify
a different .NET run-time version for makeres.exe,
comment (with REM) the line in build.bat that calls
setdotnetver.exe and modify makeres.exe.config file manually.
|
It is recommended NOT to modify the starter template code that comes with .NETZ source code (despite this being easy), unless you have a strong reason to do so. A modified starter template needs to be maintained explicitly, when a new .NETZ version comes out. .NETZ may be updated at any time and there is no warranty that the modified custom starter templates will be compatible with the new version. Custom modifications of the starter template are NOT supported, so modify it on your own risk. If you want to modify the compression related code, use the compression provider interface, which is supported. Use the -b (batch) option if you need to modify the starter code only for your solution.
^ top