.NETZ Help and Usage Examples II
EXE Assembly Attributes
The custom attributes explained in the section affect only the main EXE file, not the DLLs. .NETZ processes automatically the following attributes for the main assembly (EXE file) and copies their values to the packed EXE:
System.Reflection.AssemblyCompanyAttribute
System.Reflection.AssemblyConfigurationAttribute
System.Reflection.AssemblyCopyrightAttribute
System.Reflection.AssemblyCultureAttribute
System.Reflection.AssemblyDescriptionAttribute
System.Reflection.AssemblyProductAttribute
System.Reflection.AssemblyTitleAttribute
System.Reflection.AssemblyTrademarkAttribute
System.Reflection.AssemblyVersionAttribute
Unhandled attributes can be usually safely ignored. To see the attributes that are not processed by .NETZ use the -aw flag. In this case a warning will be reported for every non processed attribute.
It seems that "System.Windows.Forms.Application.ProductName" has
some undocumented behaviour. Normally, it should
return the value set in the AssemblyProductAttribute. However when this
attribute is not set, the "System.Windows.Forms.Application.ProductName" will
return the start up namespace name. .NETZ changes the
start up namespace to "netz". If this is a problem
(reported by Hadobás Attila,
attila [at] hadobas.com), then make sure you explicitly set
the "AssemblyProductAttribute" in your application.
For example, in C#, one could use:
using System.Reflection;
using System.Runtime.CompilerServices;
[assembly: AssemblyProduct("MyApplication")]
Then compile your application as usual and compress it
with .NETZ. .NETZ will not change the
AssemblyProductAttribute value.
If your main (EXE) assembly uses (custom) attributes other than the ones in the list above (usually set in the AssemblyInfo.cs in the Visual Studio generated projects) then you need to set these attributes manually.
Other custom attributes can be specified in a text file and passed to .NETZ using the -a option. The syntax should be similar to the one Visual Studio uses for AssemblyInfo.cs file in C# applications, e.g.,
[assembly: AssemblyDelaySign(true)].
Another way to specify custom attributes is to use the -b option. It will generate an AssemblyInfo.cs file in Visual Studio format that you can modify to place any custom attributes for the main assembly.
In order to handle the following strong-name related attributes, see Signing the Packed EXE File:
System.Reflection.AssemblyKeyFileAttribute
System.Reflection.AssemblyKeyNameAttribute
System.Reflection.AssemblyDelaySign
See also: Limitations | The Batch Option
^ top
DLL Private Paths
If app.exe makes use of private paths and expects for example that lib2.dll be inside a subdirectory called 'bin', then you can simply place the packed version of lib2.dll, that is lib2z.dll in the same folder. The .NETZ starter code can find zipped DLL-s in private paths in the same way as .NET does. .NETZ also supports cultures.
If app.exe does not use private paths, but you would like to use them with the packed version then you can specify them with the -p option:
netz app.exe lib2.dll -p bin
You have to create the 'bin' directory manually and place any *z.dll files that you like there. All private paths will be searched. To specify more than one private path, separate them by ‘;’:
netz app.exe lib2.dll -p bin1;bin2
Private paths are relative to the directory where app.exe is found. Absolute paths are not accepted. You have to place the *z.dll or *.dll files manually in the intended private path directories.
If you pack the DLL files inside the EXE file with the -s option, there is no need to set this option, unless you have other unpacked DLLs that use it. (Even if you set private paths when you do not use them, it is not an error.)
The way that the .NETZ handles private paths was depreated in .NET 2.0 (CS0618), however it still works ok.
See also: Limitations | Single EXE | Compression | Remoting
^ top
Compression Provider Options
The following options -r, -z, and -l are used with compression providers. The -z and -l serve to fine tune the way the redistributable decompression DLLs (if any) are handled. See also: Compression Providers.
The -r Option
The -r option allows to select another compression provider. Default is defcomp.dll. Example:
netz -r net20comp.dll app.exe lib1.dll
This command tells .NETZ to use the .NET2 2.0 compression provider that requires no redistributable DLL file (no zip.dll is needed). The net20comp.dll provider is valid only for .NET 2.0 and has a lower compression ratio than the default provider.
The -z Option
In general a compression provider may require that you distribute a decompression DLL with the packed applications. For example, by default .NETZ uses the defcomp.dll to compress the files. The defcomp.dll requires that you redistribute the zip.dll file with the packed applications.
Not all compression providers may require that you redistribute a decompression DLL. For example, net20comp.dll does not add any additional DLL to the packed applications (.NET 2.0 only).
If a compression provider has a redistributable DLL, as it is the case with zip.dll for defcomp.dll, then the redistributable DLL (zip.dll file) cannot be compressed. It can however be packed using the -z option. This option is ignored in the provider does not specify a redistributable DLL and no -l option is present. For example:
netz -z -s app.exe lib1.zip
The -z option is valid only when an EXE file is specified and when the compression provider has specified a redistributable compression DLL file name. The default compression provider specifies zip.dll file (a recompilation of #ZipLib).
The -z option packs the redistributable compression DLL file (default zip.dll) as a resource of the EXE file, so you do not have to distribute it separately with compressed app.exe. The redistributable compression DLL file (zip.dll) file is, however, not compressed, so this option does not
make the overall size smaller. It is provided only as a convenience. The zip.dll assembly is strongly named.
The -l Option
The -l option overwrites the name of the redistributable compression DLL file returned by the compression provider, if any, (default zip.dll) with a custom name. The given DLL with the new name must exist.
For example, one should not use the name "zip.dll" for another application DLL file, when the default compression provider is used (defcomp.dll) as this is used by .NETZ. You can however rename zip.dll to a new name (and reuse "zip.dll" for your DLL files). If you want to use another file name ( name) then use the -l option to tell it to .NETZ:
netz app.exe -l ICSharpCode.SharpZipLib.dll
.NETZ will now use the ICSharpCode.SharpZipLib.dll instead of zip.dll. The specified #ZipLib ICSharpCode.SharpZipLib.dll file must exist. The default value is zip.dll.
Note: If your original application uses #ZipLib then you do not need to distribute zip.dll when using defcomp.dll. You need however to link the starter with #ZipLib's original DLL file (ICSharpCode.SharpZipLib.dll), not with zip.dll. Use the -l option to name ICSharpCode.SharpZipLib.dll as the default ZIP library for this purpose.
Do not specify -l, when the compression provider has no redistributable DLL file, as is the case with the net20comp.dll.
See also: Compression Providers.
^ top
Licensed Components and Controls
.NETZ handles automatically EXE files that contain .NET licensed components information (generated with lc.exe), by automatically processing app.exe.licenses data when found. There is no need for any special user interaction.
If for any reason, you find that .NETZ fails to set the license information properly, then use the -b option to provide this information manually (using /res:app.exe.licenses).
See also: The Batch Option
^ top
Signing the Packed EXE File
.NETZ works transparently either with signed (strong named assemblies), or unsigned assemblies. By default, the packed EXE file is not strongly named. If strongly named assembly EXE file is packed, it is preserved as strong named and will run as such.
.NETZ offers several options to sign the packed EXE (-kf, -kn, -kd, -ka). These options mimic the use of the following attributes:
System.Reflection.AssemblyKeyFileAttribute
System.Reflection.AssemblyKeyNameAttribute
System.Reflection.AssemblyDelaySign
The -kf, -kn, -kd options only set the above final assembly attributes. The compiler then uses these attributes to sign the exe. For example, to specify a key file app.snk to use to sign the packed EXE for app.exe use:
This will set: [assembly: AssemblyKeyFile("app.snk")]. Only the packed EXE is signed, not the original app.exe. Similarly you can use the -kn keyName option to specify a key name. See the .NET documentation for details what a key name or a key file are and how a key name or key file is resolved. To delay sign specify the additional option -kd.
You could also reuse the original key file, or key name information found inside a signed app.exe. This was the default behavior of .NETZ before version 0.2.8. To achieve this, use the -ka option:
In this case, .NETZ will check the app.exe for the above attributes, and for the System. Reflection. AssemblyAlgorithmIdAttribute, and reuse them for the packed EXE. Another way to explicitly set the System. Reflection. AssemblyAlgorithmIdAttribute attribute is to use the -a option. Often the file specified in the AssemblyKeyFileAttribute uses a relative path. For this reason, make sure this path can be reached exactly from the folder where you are running .NETZ. For example, if app.exe is created in Visual Studio and uses app.snk found in the project directory (.), then the path used for the key file in AssemblyKeyFileAttribute will be @".\.\app.snk". This means that you can safely run .NETZ with -kf from the .\bin\Release or the .\bin\Debug folder, because the path depth matches. If in doubt, use the -b option.
If -ka is specified, then -kf and -kn are ignored, unless no key file, or key name attributes are found in the app.exe. Check the .NET documentation for the requirements of the linked assemblies before you sign the packed EXE. The redistributable zip.dll file that comes with .NETZ is strongly named and can be safely used with signed EXEs.
^ top
Service Support (-sr, -srp)
.NETZ offers some very basic support to create NT services from arbitrary EXEs (thanks to Marc Clifton, marc.clifton [at] gmail.com). To turn any console EXE to a Windows service append -sr to the usually .NETZ path:
netz -s -z app.exe lib1.dll -sr
It will create a Windows service from the non-service app.exe. The original app.exe will be run inside a Windows service thread, so you do not need to run a thread on your own. The original app.exe can run a loop inside its Main method where it does the work. Any command-line arguments will be passed to its Main() method. A sample app.exe may look as follows:
using System;
class MyService {
public static void Main(string[] args) {
// process args
while(true) {
// do something
System.Threading.Thread.Sleep(...);
}
}
}
By default, the services are named "netz service timestamp". To specify another name and other parameters, use the -srp option. The -srp should point to a text file where the parameters are found. The format of the file is parameterId=paramterValue. The strings should not be put in quotes. For example:
netz -s -z app.exe lib1.dll -sr -srp service.txt
Where the service.txt may look as follows:
#password=
#userName=
helpText=Netz service help text. Help must be one line. No quotes.
displayName=Netz Service
serviceName=Name must be unique!
#startType=System.ServiceProcess.ServiceStartMode.Automatic
Lines starting with # in service.txt are ignored. By default password and username are null.
The services support is very basic. To get an idea what kind of service code is generated, use the -b option and have a look at the generated code. The code generated with the -b option can also serve as a starting point for custom modifications of the service code.
To install the .NETZ generated service use the installutil.exe from the .NET SDK:
To start the service use:
net start "your service name"
To stop the service use:
net stop "your service name"
To uninstall the service use:
^ top