Converting Typepad Exported Blog format to BlogML
Executing Powershell Scripts in the Same Execution Context

InterOp: Using a .NET based component from a non .NET platform by creating Isolated Application

Whenever we try to use a .NET component from VB6 or VC++ applications we tend to expose the .NET classes as COM components and register them and from the VB6 or VC applications so that we can instantiate and use the COM components written in .NET. One downside to doing interOp this way is the use of Registry to store the COM information as COM uses registry to lookup the prog id and clsid. This hassle can be avoided by using xcopy deployment with Registry Free COM.

Isolated Applications and Side by Side Assemblies

.NET is not the sole platform to come up with xcopy deployment and freedom from dll hell. Cpp and Delphie had this for long time. Isolated Applications and Side by side Assemblies  have been invented as a solution to the versioning problem.

According to MSDN, Isolated Applications are self-describing applications installed with manifests. The benefits of Isolated Applications are that these are more stable and reliable since they are not affected by installation or change in other software, they will always run with the component version they were originally intended for, they can take advantage of Side by Side Assemblies feature, can be installed with xcopy deployment without impacting the registry. A side by side assembly can be a dll, windows class, COM server, type library or interface defined by manifests.

Private and Shared Assembly

There are two types of Side By Side Assemblies. Private Assemblies are those which are for consumption of one single application, usually placed in the application folder or sub folder. But a Shared Assembly can be used by multiple applications. A fully Isolated application uses only side by side assemblies. If you want to find the Shared Assemblies installed in your computer look in \Windows\WinSxS folder. The shared assemblies are installed here.

Manifests

Manifests are xml files that accompany assemblies with extra information like dependency, binding, activation. A manifest can be an external file or can be embedded as a resource within the assembly. In older operating systems like Windows XP, manifests need to be embedded inside the side by side (denoted SxS) assemblies to work properly. Assembly Manifests describe side by side assemblies and thus needs to be embedded to work properly in operating systems like Windows XP. Application Manifests describe isolated applications and do not need to be embedded inside the application.

Normal Registry Based COM Component Load Procedure

If we look up a COM self registering dll we will find that it usually* has four stdcall  calling convention functions. Look at the dependency walker image below of a standard self registering COM server dll.

dependency_walker

When we use regsvr32.exe to register a COM dll, the register server application calls the DllRegisterServer function of the dll and that function call inside the dll takes care of putting information in the windows registry so that it can be used by any user application. Now lets have a look at the registry where all these information is recorded. Let us take a standard windows COM component and see its registry structure. The COM component that we will look up today is FileSystemObject from Micorsoft scripting runtime. The progid of the object is Scripting.FileSystemObject. Lets say we are using script code like this

 Set fso = CreateObject( “Scripting.FileSystemObject” )

So lets try to have an understanding how this object is created from the code above. If we go and try looking up the string “Scripting.FileSystemObject” under the HKEY_CLASSES_ROOT key then we would see this.

registry_1

As you can see there is a node called CLSID and it contains the Class ID ( GUID of the class) inside the node. Now lets go and visit that Class ID node under the HKEY_CLASSES_ROOT\CLSID registry node. See below

registry_2

As we can see that this is how the dll containing the class object is found, COM infrastructure then calls the DllGetClassObject function to retrieve a pointer to the object we are looking for. As like all COM interfaces the object implements IUnknown interface and all scriptable COM objects implement IDispatch interface. However how COM identifies and uses the object beyond the scope of this article. The point that I wanted to make is that the windows registry has a very important function here and to have any COM component usable by other applications we had to register it in windows registry. 

Registry Free COM Access in an Isolated Application

In an Isolated Application we can skip entering all the information in the registry and rather enter them in the manifest. We need to create an application manifest which will have the filename in the format of application.exe.manifest. Then we need to create an assembly manifest and embed that assembly manifest inside the dll. Then we would have created an Isolated Application and would not need to register to windows registry to access the functions of the COM dll.

The side by side assemblies are searched in the following order

1. In the executable folder
2. Subfolder of the executable folder, subfolder must have the same name as the assembly. For example see inside your Windows\WinSxS folder
3. In language specific or culture specific subfolder of the executable

For more information on assembly search order look here in MSDN.

Activation Contexts are data structures that allows the OS to redirect loading. For example it can redirect the loader to load a specific version of a dll, or redirect COM object loading process. We will use the COM object loading redirection to avoid using windows registry. For more information on Activation Contexts read this

Doing it by example

I have setup a sample application with source that will show how we can create a registry free COM component. Please note that there is already a practical example in the following article in MSDN, Registration-Free Activation of .NET-Based Components: A Walkthrough by Steve White and Leslie Muller. You might want to read that article if you find my example not clear enough.

Download Sample Code

Here is what we are going to do in the sample application

1. Create C# based class that serves funny quotes and expose that as a COM component and register it.

2. Create a VB6 executable that uses the COM dll to show quotes

3. Unregister the COM dll to show that without COM registration in windows registry the application is no longer working

4. Create an application manifest, then create an assembly manifest and recompile the C# application with the embedded assembly manifest to create our isolated application.

5. Move the isolated application to a different folder and prove that the application is using COM without registry.

1. C# COM Dll

We are going to create a dll called QuoteSource and a class that serves Quotes called QuoteProvider and it is going to implement the IQuoteProvider interface. The methods in the interface will be exposed.

Here is how the interface looks like.

 interface_1

Here is the class that serves quotes and implements the interface above

class_1  ‘

The assembly info contains the assembly guid

assembly_info

We need to make sure that a tlb file is generated and the assembly we created is registered. We will select “Register for COM interop” option from the build properties screen. See below …

build

2. VB6 Client Executable that uses the C# Library

We have created a simple VB6 application that refers and calls the C# assembly dll. See below:

VB6Client

Let compile the executable and it becomes VB6Client.exe

3. Unregister the C# COM dll to make sure that we a re not using the reference

We will use the following command line in the folder where the dll resides

regasm /u QuoteSource.dll

Lets run our VB6Client.exe and press the Get Quote button… walla! It does not work anymore. The executable exits with automation error since we unregistered it from windows registry.

4. Create the Application and Assembly Manifest and embed Assembly Manifest inside the QuoteSource.dll

First we are going to create an application manifest. The application manifest has to have the name in the format of exetutable full name + .manifest. Since our executable is called VB6Client.exe our application manifest will be called VB6Client.exe.manifest. Here are the contents of the manifest.

asm_manifest

Now lets create the assembly manifest and embed it inside out QuoteSource.dll. First we will create an xml file called QuoteSource.manifest. Please observe that we have put in the progid and clsid of the COM exposed class.

asm_manifest2

Now we need to convert this assembly into a resource file. We will use rc.exe that comes with windows SDK, or VC++ or VB6 installation.

We will create a text file called QuoteSource.rc  will put in the following line here.

1 24 QuoteSource.manifest

Here 1 is the manifest resource id and 24 means that it is a type of manifest resource. We will now invoke the Windows SDK resouce compiler from the command line. Check where in you computer you have the resource compiler installed. Here is the command line

rc.exe QuoteSource.rc 

After invoking this it will create a file called QuoteSource.res. This is a windows resource file.

Now we will use a custom build command to create the dll. Observe the command line below

csc /t:library /out:QuoteSource.dll /win32res:QuoteSource.res 

IQuoteProvider.cs QuoteProvider.cs Properties\AssemblyInfo.cs

See the win32res switch, it tells the compiler that it is a win32 resource.

Now copy the dll to the same folder as the exe, also copy the application manifest. There is no need to copy the assembly manifest as we have already embedded it inside the dll.

Run the the application and press the Get Quote button, it works!

5. XCopy Deployment

Copy or move the folder elsewhere, even to another computer. It will still work without any need to register the .NET COM dll. This is because we have created the application and assembly manifest and windows is treating our application as a Isolated application.

Last Words

This way you can create XCopy deployment for even COM based applications and avoid storing information in registry. Even a multi dll VB6 or VC++ application can be made Isolated Application.

kick it on DotNetKicks.com

Comments

Razan Paul

Great Work. Thanks...............

Habibh

"Registry Free COM" never heard before, never read before. Thanks for very very important blog entry.

Shafqat Ahmed

Thank you for your comments.

gslysz

Thanks very much for your posts. I'm really benefiting from them.

ravynsistr

down long cupcake probably revolution fourth

eef

thanks alot!

Ejaz

dear,i have motorolla wireless usb adapter. i have installed its driver, but i want to access device information like RSSI and CINR from C#.net. can i use the DLL provided in installation folder of the driver to get the information??? or can you pls telme the way to access those variables??
thanks

Verify your Comment

Previewing your Comment

This is only a preview. Your comment has not yet been posted.

Working...
Your comment could not be posted. Error type:
Your comment has been saved. Comments are moderated and will not appear until approved by the author. Post another comment

The letters and numbers you entered did not match the image. Please try again.

As a final step before posting your comment, enter the letters and numbers you see in the image below. This prevents automated programs from posting comments.

Having trouble reading this image? View an alternate.

Working...

Post a comment

Comments are moderated, and will not appear until the author has approved them.

Your Information

(Name and email address are required. Email address will not be displayed with the comment.)