Salamander .NET Linker and Mini-Deployment Tool

Code Samples

Here we list some non-trivial samples. The code is directly generated with our linker tool. You can follow the instructions to generate the code by yourself if you purchase the software.

  1. Console Application - SimpleTest.exe
  2. Windows Forms Application - Scribble.exe
  3. Stock Web Service Sample - StockQuoteWebServiceClient.exe
  4. Web Browser Control Sample - WebBrowserTest.exe
  5. Windows Service Sample - BeepService.exe
  6. Managed DirectX Sample
  7. Managed and Unmanaged COM Sample

1. Console Application: SimpleTest.exe

SimpleTest.exe is a typical console application, since it only depends on mscorlib.dll, there is nothing to link. However, it can be mini-deployed. The mini-deployment is included in the same package as the following windows forms application, described in section 2. This also demonstrates the concept of deploying multiple applications together, so the common runtime libraries can be shared, and thus save disk space.

2. Windows Forms Application - Microsoft Visual Studio .NET Scribble Sample

Download .NET 2.0 version of the linked and mini-deployed Scribble.exe

This sample, Scribble.exe, is a C# MDI Drawing Application, which is located in the samples folder from Visual Studio .NET installation.

(1) Linking the code    download original and linked code here

If you want to browse the original code, please click here. It contains a few classes that are typical of Windows Forms Application. The exe refers to the following assemblies: (click the Manifest node to see the referenced assemblies)

The linker selectively links types and methods from all of the above assemblies except for mscorlib.dll, the resulting assembly contains only those portions of code required to run the application. The linked code can be browsed here, you can note there is now only one reference - mscorlib.dll. This special dll, mscorlib.dll, is the system assembly that has special runtime types required by the execution engine, and it is the only assembly that can not be linked.

There is one runtime problem with the linked scribble.exe, which is to do with code access security. You can test it out by selecting File > Print Preview, or File > Print... menu, a security exception box will show up. The security exception is caused by the failure of a System.Security.Permissions.StrongNameIdentityPermission, which enforces the existence of a strong named System.Windows.Forms.dll. Since we have already linked it into the exe, so the dll no long exists as an independent identity, and therefore the exception is thrown. Fortunately, such runtime problems can be corrected when we mini-deploy the application. Section (2) below uses a special registry setting to inform the runtime to ignore the security check, and the mini-deployed scribble.exe is still able to run as usual, namely, Print and Print Preview work the same as the original assembly.

(2) Mini-deploy the code    download mdeployed code here

This zip file contains a minimum set of the Microsoft .NET Framework plus the Scribble application (Scribble.exe) and a simple console application (SimpleTest.exe). This is everything that you need to ship to your customers. The zip file can be simply unzipped to a bare machine without .NET Framework, and your application will run as if the whole framework is installed. There are no entries to add into the client's registry. The installation takes no time. Imagine you have a cool game written in .NET, this mini-deployment will definitely increase your customer base as most of your potential customers probably do not want to install the whole set of Microsoft .NET Framework.

Below is the file list of the mini-deployment package. Two files, msvcr70.dll and GdiPlus.dll are included in case the client machines do not have them. Most machines should already have these two files. In other words, the zip file could be further trimmed.

(3) Launch from a CD

If you burn a CD with the mini-deployment package shown above, you can insert the CD to a PC that does not have Microsoft .NET Framework installed, and the two applications can be launched simply by double clicking them. It has been tested on Windows XP, Windows 2k, Windows NT, Windows ME and Windows 98 machines (client and server edition). 

Mini-deployed applications also run on machines that have the full .NET Framework installed, in which case, they executes in an isolated fashion using the integrated and slimmed framework, and thus conflicts are avoided. When later on, the client machine installs the full .NET Framework, it will have no impact on the mini-deployed applications.

3. Web Service Sample - Delayed Stock Quote Service   Download code Here

This is a windows forms client that invokes a public web service. The web service is the delayed stock web service as described at http://www.xmethods.com. The application allows you to enter a stock symbol, the stock price will be retrieved from the web service and displayed in the windows form. The application may not run in the presence of a firewall.

(1) Linking the code

The exe refers to a large number of assemblies and modules, as listed below (Load the exe into our .NET Explorer, right click Dependencies Node, select Show All Dependencies recursively to get the list):

  • mscorlib.dll
  • Accessibility.dll
  • cscompmgd.dll
  • Microsoft.VisualC.dll
  • System.dll
  • System.Data.dll
  • System.DirectoryServices.dll
  • System.Drawing.dll
  • System.EnterpriseServices.dll
  • System.EnterpriseServices.Thunk.dll
  • System.Runtime.Remoting.dll
  • System.Runtime.Serialization.Formatters.Soap.dll
  • System.Web.dll
  • System.Web.RegularExpressions.dll
  • System.Web.Services.dll
  • System.Windows.Forms.dll
  • System.Xml.dll 

The linker selectively links types and methods from all of the above assemblies except for the following assemblies:

  • mscorlib.dll - system assembly required by the CLR runtime.
  • System.EnterpriseServices.Thunk.dll (63KB) and Microsoft.VisualC.dll (6KB) - VC++ .NET assemblies containing native code.
  • System.Xml.dll and its dependent System.dll - Web service utilizes XML serialization, which involves dynamic generation of temporary assemblies. Temporary assemblies are generated at runtime by compiling emitted C# code with the C# compiler (csc.exe). The emitted C# code uses the System.Xml namespace, and thus System.Xml.dll needs to be kept as unlinked, so is its dependent dll - System.dll. (There are means to link two assemblies into the exe, but more config files needs to be modified).

The linked EXE does not run under the normal .NET Framework because some config file needs to be modified to reflect the link of assemblies. When mini-deployed, config files are only used by the deployed application and thus can be tailored to make the application to run, see below.

If you do not want to bother with modifying config files, you can actually perform mini-deployment without linking; However, the resulting package will be much larger in size since all of those 17 dependent assemblies above must be deployed along with the EXE.

(2) Mini-deploy the code

After link, we have a large EXE file containing much fewer references. This EXE is now ready to be mini-deployed with our tool.

The generated mini-deployment contains a special directory, v1.1.4322\CONFIG, which holds config files for the application. One config file, machine.config, has a configuration section handler (shown below), which requires System.Web.Services.dll to handle it. Since this DLL is already linked into the exe, the config file needs to be modified to update the type specification to reflect the change. A type is fully qualified with type name and its enclosing assembly. The linker tool will automatically perform the modification as shown below:

								
<sectionGroup name="system.web">
   <section name="webServices" type="System.Web.Services.Configuration.WebServicesConfigurationSectionHandler, 
	 System.Web.Services, Version=1.0.5000.0, Culture= neutral, PublicKeyToken= b03f5f7f11d50a3a"/>
</sectionGroup>
								

needs to be changed to the following:


<sectionGroup name="system.web">
	<section name="webServices" type="System.Web.Services.Configuration.WebServicesConfigurationSectionHandler, 
	  StockQuoteWebServiceClient"/>
</sectionGroup>
									

With this modification, the linked web service application after mini-deployment in the linked\mdeployed  directory runs same as the original assembly.

(3) Launch from a CD

If you burn a CD by copying the whole generated mdeployed directory, the web service client can be launched directly from the CD. You can simply insert the CD to a PC that whether or not have Microsoft .NET Framework installed, and the application runs by simply double clicking the EXE. It has been tested on Windows XP, Windows 2k, Windows NT, Windows ME and Windows 98 machines (client and server edition).

4. Web Browser Control Sample   Download code Here

This is a windows forms application hosting the Microsoft Web Browser Control. It simply uses the control to display Remotesoft home page, and allows you to navigate page links. The exe, WebBrowserTest.exe, utilizes two COM interop assemblies, Interop.SHDocVw.dll and AxInterop.SHDocVw.dll , to communicate with the control. This sample shows how to link interop assemblies into an application.

(1) Linking the code

The exe refers to a large number of assemblies and modules, as listed below (Load the exe into our .NET Explorer, right click Dependencies Node, select Show All Dependencies recursively to get the list):

  • Interop.SHDocVw.dll
  • AxInterop.SHDocVw.dll
  • mscorlib.dll
  • Accessibility.dll
  • System.dll
  • System.Drawing.dll
  • System.Runtime.Serialization.Formatters.Soap.dll
  • System.Windows.Forms.dll
  • System.Xml.dll 

The linker selectively links types and methods from all of the above assemblies except for the following assemblies:

  • mscorlib.dll - system assembly required by the CLR runtime.

The linked EXE runs the same as the original EXE under the regular Microsoft .NET Framework.

(2) Mini-deploy the code

After link, we have a large EXE file containing much fewer references. This EXE is now ready to be mini-deployed with our tool.

The mini-deployment is generated in the linked\mdeployed directory, which can be deployed to machines w/o .NET Framework, and it runs the same as the original assembly.

(3) Launch from a CD

If you burn a CD by copying the whole generated mdeployed directory, the application can be launched directly from the CD. You can simply insert the CD to a PC that whether or not have Microsoft .NET Framework installed, and the application runs by simply double clicking the EXE. It has been tested on Windows XP, Windows 2k, Windows NT, Windows ME and Windows 98 machines (client and server edition).

5. Windows Service Sample - BeepService.exe   Download code Here

This sample, BeepService.exe, is a simple windows service developed in C#. When the service is running, you will hear beeps every 3 seconds. Make sure your speaker is turned on. This sample contains the following directory structure:

BeepService        --- the original code
  |
  |- mdeployed      --- the mini package for the original code
  |
  |- linked             --- the linked code
        |
        |- mdeployed --- the mini package for the linked code

 

(1) Testing the original service

The original service contains 2 assemblies: BeepService.exe and BeepLib.dll. BeepService is the main assembly that refers to BeepLib which implements the beeping functionality. The following are the steps to test the service: (make sure the framework dir, e.g., c:\windows\microsoft.net\framework\v1.0.3705, is in the PATH environment variable)

  • Installing the service

    InstallUtil.exe BeepService.exe

  • Starting the service

    Now go to Control Panel > Administrative Tools > Services, and locate the service named as Remotesoft Beep Service Sample , right click Start, and you should start to hear beeps every 3 seconds. Make sure the speaker is turned on.

  • Stopping the service

    Now go to Control Panel > Administrative Tools > Services, and locate the service named as Remotesoft Beep Service Sample , right click Stop, and the beeping will stop.

  • Un-installing the service

    InstallUtil.exe /u BeepService.exe

(2) Mini-deploy the original service

To mini-deploy the service, run the tool on BeepService.exe and InstallUtil.exe respectively, and a directory, mdeployed, is created. This directory contains everything that you can simply copy to a machine that does not have .NET Framework installed, and the service runs the same as the original service.

You can test the mini package as described in (1) above, namely you can install, start, stop and uninstall the service from the mdeployed directory, and it behaves the same as the original service. Make sure you are using the generated InstallUtil.exe to install and uninstall the service.

(3) Linking the original service

The BeepService.exe service refers to the following assemblies: (click the Dependencies node under .NET Explorer, right click Show All Dependencies recursively  to see all referenced assemblies)

  • Accessibility.dll
  • BeepLib.dll
  • mscorlib.dll
  • System.dll
  • System.Configuration.Install.dll
  • System.Drawing.dll
  • System.Runtime.Serialization.Formatters.Soap.dll
  • System.ServiceProcess.dll
  • System.Windows.Forms.dll
  • System.Xml.dll

The linker selectively links types and methods from all of the above assemblies except for mscorlib.dll, the resulting assembly only contains those portions of code required to run the application. Make sure the System.Configuration.Install.ManagedInstallerClass class and the BeepService.ProjectInstaller class are linked into the final assembly. The linked service contains now only one reference - mscorlib.dll, which is the system assembly that has special runtime types required by the execution engine, and it is the only assembly that can not be linked.

The BeepService.exe requires the framework utility InstallUtil.exe at installation time, however, since all underlying framework assemblies are linked into the service, we can not use the original InstallUtil.exe. A custom version of InstallUtil.exe is provided by our linker tool, and a copy is contained in the same dir as the linked BeepService.exe, this special InstallUtil.exe dynamically loads the System.Configuration.Install.ManagedInstallerClass class from the BeepService.exe, instead of System.Configuration.Install.dll .

This special version of InstallUtil.exe does not run correctly on the linked BeepService.exe . It throws the following error:

Microsoft (R) .NET Framework Installation utility Version 1.0.3705.288 Copyright (C) Microsoft Corporation 1998-2001. All rights reserved. Could not create System.Diagnostics.DiagnosticsConfigurationHandler, System, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

This is due to the linking of System.dll into the EXE, so the desired configuration handlers defined in machine.config can not be found. This error can be corrected in two ways: (1) leave System.dll out from the linking process; (2) modify the machine.config file in the mini deployment package. We use method (2) to make it to work, as described in the next section.

(3) Mini-deploy the linked service

Both BeepService.exe and InstallUtil.exe in the linked directory need to be mini-deployed, the resulting package is in the mdeployed directory. The configuration file,  v1.0.3705\config\machine.config, needs to be modified to reflect the fact that System.dll has been linked into BeepService.exe. Our tool automatically detects such changes, and will generate the correct machine.config file. A segment of the file is shown below:

								
<section name="runtime" type="System.Configuration.IgnoreSectionHandler, BeepService" allowLocation="false"/>
<section name="mscorlib" type="System.Configuration.IgnoreSectionHandler, BeepService" allowLocation="false"/>
<section name="startup" type="System.Configuration.IgnoreSectionHandler, BeepService" allowLocation="false"/>
<section name="system.runtime.remoting" type="System.Configuration.IgnoreSectionHandler, BeepService" allowLocation="false"/>
<section name="system.diagnostics" type="System.Diagnostics.DiagnosticsConfigurationHandler, BeepService"/>
<section name="appSettings" type="System.Configuration.NameValueFileSectionHandler, BeepService"/>
								

The original content in the machine.config file is shown below; note that the System assembly is changed to BeepService because we have linked System.dll into BeepService.exe .


<section name="runtime" type="System.Configuration.IgnoreSectionHandler, System, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowLocation="false"/>
<section name="mscorlib" type="System.Configuration.IgnoreSectionHandler, System, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowLocation="false"/>
<section name="startup" type="System.Configuration.IgnoreSectionHandler, System, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowLocation="false"/>
<section name="system.runtime.remoting" type="System.Configuration.IgnoreSectionHandler, System, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowLocation="false"/>
<section name="system.diagnostics" type="System.Diagnostics.DiagnosticsConfigurationHandler, System, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
<section name="appSettings" type="System.Configuration.NameValueFileSectionHandler, System, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>

After modifying the configuration, the mini package of the linked service works fine. You can test the linked and mini-deployed service in the linked\mdeployed directory as described in (1) above, namely, you can install, start, stop and uninstall the linked version, and they behave the same as the original service (Make sure that the custom InstallUtil.exe in the same dir is used).

The linked and mini-deployed package is about 3MB smaller than the directly mini-deployed package of the service. Since the difference is not that much, you may not perform the linking at all, since it is somewhat tricky.

6. Managed DirectX Sample Download code Here

This is a tutorial type application of managed DirectX, more info can be found at http://www.thecodeproject.com/cs/media/mdxtutorial2.asp . Although this is a simple program, the same principle applies to complicated DirectX applications, such as commercial games developed with managed DirectX.

The executable refers to the following DirectX assemblies:

  • Microsoft.DirectX.dll
  • Microsoft.DirectX.AudioVideoPlayback.dll
  • Microsoft.DirectX.Direct3D.dll
  • Microsoft.DirectX.DirectDraw.dll

Since these files are mixed assemblies that contain native code, there is nothing we can link into the EXE. However, we can still generate mini-deployment package so the exe can be deployed to machines that do not have the .NET Framework installed. The generated package is in the mdeployed directory. You can copy the directory to machines w/o the framework, and the application still runs as if the whole framework is installed.

Launch from a CD

If you burn a CD with the mini-deployment directory as described above, you can insert the CD to a PC that does not have Microsoft .NET Framework installed, and the application can be launched simply by double clicking it.

7. COM Component Sample   Download code Here

This sample illustrates the steps necessary to deploy applications that invokes native and managed COM components. Most importantly, this sample explains how to add entries to the virtual registry to support COM registration. This application contains the following files:

  • managed exe, client.exe
  • managed COM assembly, ManagedCom.dll
  • native COM component, NativeCom.dll
  • interop assembly, NativeCom.Interop.dll, for the native COM dll.

The exe invokes the native COM dll, which in turn invokes the managed COM. Both COM dlls need to be registered before the exe can execute correctly.

(1) COM Registration under regular environment

In order to run the exe correctly, you would register them with the following commands:

  • regasm.exe ManagedCom.dll
  • regsvr32.exe NativeCom.dll (or on Windows 98: regsvr.exe NativeCom.dll) 

Now you can successfully executes the exe, and it prints out a few tests results on data marshaling. If you don't perform the above registration, a Class Not Registered exception will be thrown.

(2) Linking the code

Since the exe is a simple console application, it does not refer to many assemblies. The references are listed below (Load the exe into our .NET Explorer, right click Dependencies Node, select Show All Dependencies recursively to get the list):

  • ManagedCom.dll
  • NativeCom.dll (native module)
  • Interop.NativeCom.dll
  • mscorlib.dll

Because ManagedCom.dll is used as a COM component, and thus it can not be linked into the exe. The linker only links the interop assembly, Interop.NativeCom.dll. .

The linked EXE runs the same as the original EXE under the regular Microsoft .NET Framework provided the COM registration is performed as described in (1).

(3) Mini-deploy the code and COM Registration under mini-deployment environment

The original or the linked EXE can be easily mini-deployed with our tool, and a mdeployed directory will be created that contains all of the file necessary to run the application. The generated mini-package contains

In order to make sure the exe runs well w/o the framework, we need to manually perform the COM registration before the application is deployed.

The Virtual Registry for the Mini-Deployed Applicaitons

When an application is mini-deployed, a registry file is automatically generated and stored in the format of one plain text file, mdeploy.registry. This is the virtual registry that is internal to the deployed applications. All entries, such as COM registration, that are internal to the applications can be added to this file beforehand, and thus it provides a truly zero installation scenario.

Adding Registry Entries for Managed COM

The following are the steps to add the entries for the managed COM dll.

  • Run regasm with /regfile option, e.g.
    regasm /regfile:ManagedCom.reg ManagedCom.dll
  • Open the generated .reg file, and update the path for mscoree.dll so the private copy in the same directory is used. e.g.,
    change "C:\WINDOWS\system32\mscoree.dll" to "mscoree.dll"

  • Insert the modified text into the mdeploy.registry file, and the virtual registry now contains the entries for the managed COM assemblies.

The linker tool ships a sample that illustrates how to add registry entries for native/managed COM dlls, the sample is located in samples\ComTest directory. The following lists are some of the entries generated from the above steps, and are added to the virtual registry:


[HKEY_CLASSES_ROOT\ManagedCOM.SimpleCallBack]
@="ManagedCOM.SimpleCallBack"

[HKEY_CLASSES_ROOT\ManagedCOM.SimpleCallBack\CLSID]
@="{A1DE7A8D-7E41-4F02-8FBB-BE34EE95F0BA}"

[HKEY_CLASSES_ROOT\CLSID\{A1DE7A8D-7E41-4F02-8FBB-BE34EE95F0BA}]
@="ManagedCOM.SimpleCallBack"

[HKEY_CLASSES_ROOT\CLSID\{A1DE7A8D-7E41-4F02-8FBB-BE34EE95F0BA}\InprocServer32]
@="mscoree.dll"
"ThreadingModel"="Both"
"Class"="ManagedCOM.SimpleCallBack"
"Assembly"="ManagedCom, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"
"RuntimeVersion"="v1.0.3705"

[HKEY_CLASSES_ROOT\CLSID\{A1DE7A8D-7E41-4F02-8FBB-BE34EE95F0BA}\ProgId]
@="ManagedCOM.SimpleCallBack"

[HKEY_CLASSES_ROOT\CLSID\{A1DE7A8D-7E41-4F02-8FBB-BE34EE95F0BA}\Implemented Categories\{62C8FE65-4EBB-45E7-B440-6E39B2CDBF29}]

Note that the InprocServer32 for the com is modified to mscoree.dll, rather than c:\windows\system32\mscoree.dll, indicating the assembly is instantiated using the private copy of the framework under mini-deployment environment.

Adding Registry Entries for Native COM

Normally, you would use the regsvr32 tool to register your native COM dll. You can still use regsvr32 to register a native COM when your application is installed on the target machine. In this case, the entries will be added into the global windows registry. Since our mini-deployment tool contains a virtual registry, you can take advantage of it, and thus avoid any system changes at deployment time to provide a truly zero installation scenario.

Since the current version does not provide any tools, it must be done manually. You can follow the following steps:

  • Run regsvr32.exe (regsvr.exe on Windows 98) on your native COM dll, e.g.
    regsvr32.exe NativeCom.dll
  • Run Regedit.exe utility to load windows registry, and locate the keys, then export the keys to a .reg file. This may not be easy, you need to have knowledge on the COM component.
  • Insert the modified text into the mdeploy.registry file, and the virtual registry now contains the entries for the native COM components.

The following lists are the entries generated from the above steps, and are added to the virtual registry:


# entries for NativeCom.dll
[HKEY_CLASSES_ROOT\CLSID\{1F1F59F0-BE0D-406C-860E-BF8267B38BB2}]
@="RsJni Class"

[HKEY_CLASSES_ROOT\CLSID\{1F1F59F0-BE0D-406C-860E-BF8267B38BB2}\InprocServer32]
@="NativeCom.dll"
"ThreadingModel"="Apartment"

[HKEY_CLASSES_ROOT\CLSID\{1F1F59F0-BE0D-406C-860E-BF8267B38BB2}\ProgID]
@="Comtest.RsJni.1"

[HKEY_CLASSES_ROOT\CLSID\{1F1F59F0-BE0D-406C-860E-BF8267B38BB2}\Programmable]

[HKEY_CLASSES_ROOT\CLSID\{1F1F59F0-BE0D-406C-860E-BF8267B38BB2}\TypeLib]
@="{82E27FA6-42B9-43AD-BAD4-222249916A6A}"

[HKEY_CLASSES_ROOT\CLSID\{1F1F59F0-BE0D-406C-860E-BF8267B38BB2}\VersionIndependentProgID]
@="Comtest.RsJni"						
						

Note that the path of the dll is modified so absolute path is avoided. The original windows registry contains absolute path, such as "c:\\program files\\remotesoft\\linker\\samples\\ComTest\\linked\\mdeployed\\NativeCom.dll" .

(4) Launch from a CD

If you burn a CD by copying the whole generated mdeployed directory, the application can be launched directly from the CD. You can simply insert the CD to a PC that whether or not have Microsoft .NET Framework installed, and the application runs by simply double clicking the EXE. It has been tested on Windows XP, Windows 2k, Windows NT, Windows ME and Windows 98 machines (client and server edition).


Copyright © 2008 Remotesoft Inc. All rights reserved.