A Walkthrough for Registration Free COM(C# DLL,C++ APP)

1.Introduction

     Registration-free COM is a mechanism available on the Microsoft Windows XP (SP2 for .NET Framework-based components) and Microsoft Windows Server 2003 platforms. As the name suggests, the mechanism enables easy (e.g. XCOPY) deployment of COM components to a machine without the need to register them.

On the target platforms, one of the stages of initializing a process and its dependent modules is to load any associated manifest files into a memory structure called an activation context. In the absence of corresponding registry entries, it is an activation context that provides the binding and activation information the COM runtime needs. No special code is required in the COM server or in the client unless you choose to obviate the use of files by building activation contexts yourself using the activation context API.

In this walkthrough I will build a simple .NET assembly and consume it, both registered and unregistered, from native COM clients written in Visual C++ and Visual Basic 6.0. You can download the source code and samples and see them in action right away or you can follow along with the walkthrough and build them yourself step-by-step.

2.Registration-Free COM Terminology

     Anyone familiar with .NET technology will be accustomed to the term assembly meaning a set of one or more modules deployed, named and versioned as a unit, with one module containing a manifest that defines the set. In registration-free COM, the terms assembly and manifest are borrowed for ideas that are similar in concept but not identical to their .NET counterparts.

     Registration-free COM uses assembly to mean a set of one or more PE modules (i.e. either native or managed) deployed, named, and versioned as a unit. Registration-free COM uses manifest to refer to text files with the .manifest extension containing XML, which either defines the identity of an assembly (assembly manifest) together with the binding and activation details of its classes, or defines the identity of an application (application manifest) together with one or more assembly identity references. An assembly manifest file is named for the assembly, and an application manifest file is named for the application.

The term side-by-side (SxS) assemblies refers to the configuration of different versions of the same COM component, via manifest files, in order that they can be loaded simultaneously by different threads without needing to be registered. SxS enables, and is loosely synonymous with, registration-free COM.

3.Build a .NET Assembly as a COM Server

Step 1:

     In Visual Studio .NET 2010 create a new C# Class Library Project with .NET Framework 4 and call itTestDemoLib. To have comprehensive test, the project includes different namespaces, enum type, of course and Strong Name Assembly. Implement the classes as follows:

ShowType Code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TestDemoLib.EnumType
{
    public enum ShowType
    {
        Correct,
        Incorrect,
    }
}

ITestLib Code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace TestDemoLib.Interface
{
    [Guid("D68FA677-9FFC-427A-85A3-A054199BF645")]  //IID_ITestLib
    public interface ITestLib
    {
        [DispId(1)]
        string ShowEnum(int type);
    }
}

 

TestLib Code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using TestDemoLib.EnumType;

namespace TestDemoLib.Interface
{
    [ClassInterface(ClassInterfaceType.None)]
    [Guid("4FCB8193-C906-490E-A136-6AD634E02452")]  //CLSID_TestLib
    public class TestLib : ITestLib
    {
        public string ShowEnum(int type)
        {
            if (type == 1)
                return ShowType.Correct.ToString();
            else
                return ShowType.Incorrect.ToString();
        }
    }
}


IDate Code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace TestDemoLib
{
    [Guid("969764E5-0791-48CF-9847-0A81B0D3CB75")]  //IID_IDate
    public interface IDate
    {
        [DispId(1)]
        string ShowDate();
    }
}


Date Code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace TestDemoLib
{
    [ClassInterface(ClassInterfaceType.None)]
    [Guid("AED5AF2B-5986-44F7-A816-BB6F101FA159")]  //CLSID_Date
    public class Date : IDate
    {
        public string ShowDate()
        {
            return DateTime.Now.Date.ToShortDateString();
        }
    }
}


     When you finished coding, then you should change the assembly attribute in AssemblyInfo. The attribute as fellow:

     At last, you should set TestDemoLibproject Properties.

     I've written the GUID values, which will be particular to your project, in the form of placeholders(Tools->Create GUID, and choose format 5).

Step 2:

     Create a new folder renamed as deployed in your solution address. CopyTestDemoLib.dll into\deployed.

4.Build  a Client

Step 3:

     Create a new Visual C++ Win32 Console Project called TestDemo in theTestDemoLib solution. In the Win32 Application Wizard, on the Application Settings tab, check the Add support for ATL checkbox.

     Set TestDemo Properties as fellow:

Add the following code into stdafx.h.

#include <iostream>
#include <stdlib.h>

//#import "[path]/TestDemoLib.tlb"
#import "../TestDemoLib/bin/Debug/TestDemoLib.tlb"

 

     Here, [path] should be the relative path to the type library that was generated when you built yourTestDemoLib assembly.

     Replace the contents of TestDemo.cpp with this code:

#include "stdafx.h"

void ErrorDescription(HRESULT hr)
{
	TCHAR* szErrMsg;
	if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|
		FORMAT_MESSAGE_FROM_SYSTEM,NULL,hr,
		MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),
		(LPTSTR)&szErrMsg, 0, NULL) != 0)
	{
		cout << szErrMsg << endl;
		LocalFree(szErrMsg);
	}
	else
		cout << "Could not find a description for error 0x"
		<< hex << hr << dec << endl;
}

int _tmain(int argc, _TCHAR* argv[])
{
	CoInitialize(NULL);

	HRESULT hr;
	TestDemoLib::IDatePtr datePtr;
	hr = datePtr.CreateInstance(__uuidof(TestDemoLib::Date));

	if (hr == S_OK)
		cout << datePtr->ShowDate() << endl;

	ErrorDescription(hr);

	TestDemoLib::ITestLibPtr libPtr;
	hr = libPtr.CreateInstance(__uuidof(TestDemoLib::TestLib));

	if (hr == S_OK)
	{
		cout << libPtr->ShowEnum(0) << endl;
		cout << libPtr->ShowEnum(1) << endl;
	}

	ErrorDescription(hr);

	system("pause");
	CoUninitialize();

	return 0;
}


     Build the project and run it to check if it works well. CopyTestDemo.exe into\deployed.

Step 4:

     At present the \deployed folder should contain, apart from some intermediate files, onlyTestDemo.exeand TestDemoLib.dll; and the latter will have been registered by its build process. To check that your server and client work together under these normal circumstances, run\deployed\TestDemo.exe.

Step 5:

     This walkthrough is about Registration Free COM, so we now need to unregister theTestDemoLib assembly. At a Visual Studio 2010 Command Prompt, navigate to the\deployed folder and execute the command:regasm /u TestDemoLib.dll

Step 6:

     To see what effect the previous step has had, run\deployed\TestDemo.exe again and you will see the message "Class not registered" or "Run-time error '429': ActiveX component can't create object". At this stage we have frustrated the COM runtime from finding the information it needs in the registry but we have yet to make the information available by alternative means. We will remedy that in the following steps.

5.Registration-Free Activation

5.1 Build Component Manifest

Step 7:

     In the TestDemoLib project's folder, create a private assembly manifest file (a text file) and call itTestDemoLib.manifest. Paste the following into the file:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
	type="win32"
	name="TestDemoLib"
	version="1.0.0.0"
	publicKeyToken="4f919d25f9539b29" />
<clrClass
	clsid="{4FCB8193-C906-490E-A136-6AD634E02452}"
	progid="TestDemoLib.Interface.TestLib"
	name="TestDemoLib.Interface.TestLib"
	runtimeVersion="4.0.30319.1" >
</clrClass>
<clrClass
	clsid="{9623B9FB-1EBE-30BD-8DA7-636763640C04}"
	progid="TestDemoLib.EnumType.ShowType"
	name="TestDemoLib.EnumType.ShowType"
	runtimeVersion="4.0.30319.1" >
</clrClass>
<clrClass
	clsid="{AED5AF2B-5986-44F7-A816-BB6F101FA159}"
	progid="TestDemoLib.Date"
	name="TestDemoLib.Date"
	runtimeVersion="4.0.30319.1" >
</clrClass>
</assembly>

     The content you need to add in manifest, you can refer to reg file.

------------------------------------------------------------------------------------------------------------------------------------------

     Create reg file command:

     At a Visual Studio 2010 Command Prompt, navigate to the TestDemoLib.dll folder and execute the command:regasm /regfile:TestDemoLib.reg TestDemoLib.dll

------------------------------------------------------------------------------------------------------------------------------------------

     The next task is to embed the above assembly manifest file into the above assembly as a Win32 resource. At the time of writing, this is mandatory for Windows XP, but not for Windows Server 2003. On Windows Server 2003 you can get away with simply deploying the assembly manifest file alongside the assembly. However, I urge you not to depend on this behavior as it may well change in an upcoming Windows Server 2003 Service Pack. To ensure you continue to support both platforms in the future, follow the next few steps and embed your assembly manifest file into your .NET assembly as a Win32 resource. This is only necessary for registration-free activation of .NET-based components and is not a requirement for registration-free activation of native COM components.

Step 8:

     In the TestDemoLib project's folder create a resource-definition script file (a text file) and call itTestDemoLib.rc. Paste the following into the file:

#include <windows.h>
#define MANIFEST_RESOURCE_ID 1
MANIFEST_RESOURCE_ID RT_MANIFEST TestDemoLib.manifest

     The windows.h file and its dependencies are available when you install either the Platform SDK (Core SDK section) or Visual C++. The part ofwindows.h that is required here is the definition:

#define RT_MANIFEST 24

Step 9:

     In the TestDemoLib project's folder create a build command file (a text file) and call it build.cmd. Paste the following into the file:

rc TestDemoLib.rc
csc /t:library /out:..\Debug\TestDemoLib.dll /keyfile:key.snk /win32res:TestDemoLib.res /recurse:*.cs

     What these commands do is first to invoke the Microsoft Windows Resource Compiler tool from the Platform SDK (rc.exe) to compile the resource-definition script from step 9 into a compiled resource file calledTestDemoLib.res. Next, it invokes the C# .NET compiler to build your source code file into an assembly and embed the compiled resource file into it as a Win32 resource. The compiled assembly is written to the\deployed folder but it is not registered for COM interop. If your project don’t have Strong Name Assembly, you can delete the command: /keyfile:key.snk

Step 10:

     At a Visual Studio 2010 Command Prompt, navigate to the TestDemoLib project's folder and execute the command:build

5.2 Build Application Manifest

Step 11:

     In the TestDemo project’s solution setTestDemoProject Properties as fellows:

     If your project don’t have Strong Name Assembly, you can deletepublicKeyToken. Thenrebuild the project.

------------------------------------------------------------------------------------------------------------------------------------------

     How to get publicKeyToken?

     Here, my way is to create a reg file with dll file, then open thereg file, you can findpubilcKeyToken attribute.

------------------------------------------------------------------------------------------------------------------------------------------

Step 12:

     To verify that, courtesy of the manifest files, your application is once more able to activate, run\deployed\TestDemo.exe

 

 

 

------------------------------------------------------------------------------------------------------------------------------------------

References:

     Registration-Free Activation of .NET-Based Components: A Walkthrough
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值