创建免注册(Registration Free)COM

传统的COM程序一直都需要Windows注册表的支持,如果卸载时程序没有把对应的注册表项清理干净, 可能会导致下次安装程序时出错, 同时, 如果多个程序共享一个COM Server, 一旦其中的一个程序更新了COM Server, 可能会导致其他程序不能正常运行, 也就是所谓的Dll地狱。

所幸的是, 微软早已意识到这个问题, Window XP开始, 微软提供了一种称之为Side-by-Side(WinSxs)的技术, 使得COM终于可以脱离注册表的束缚, 而我们的程序也可以以简单的X-Copy方式部署.

本文讨论如何创建和使用基于.NET的免注册COM Server.

 

首先,我们需要创建一个基于.NETCOM Server, Visual Studio (VS) 2010 + .NET4.0为例:

1. 打开VS, 新建一个Class Library (C#) 工程CSComServer4, Class1.cs改名为CSComServer4.cs并加入以下代码

namespace CSComServer4 { [Guid("F07BB298-1465-4773-8376-464446588049")] // IID [ComVisible(true)] public interface ICSComServer4 { string Version(); } [ClassInterface(ClassInterfaceType.None)] [Guid("5E6C6A71-1AF3-4169-BE2B-3E1D6C595333")] // CLSID [ComVisible(true)] public class CSComServer4 : ICSComServer4 { public string Version() { return ".NET 4.0"; } } }

你可以使用VS提供的小工具(Tools->Create GUID)来创建新的Guid.

2. Build这个Class Library工程, 将生成的CSComServer4.dll拷贝到一个单独的文件夹, 比如:”D:/demo/”.

3. 点击开始 -> 所有程序 -> Microsoft Visual Studio 2010 -> Visual Studio Tools -> 右键点击Visual Studio Command Prompt (2010) -> 选择 以管理员身份运行” (Run as administrator).

4. Visual Studio Command Prompt (2010) 窗口中输入命令 “cd /d d:/demo” 切换到demo文件夹.

5. 输入命令”regasm /tlb CSComServer4.dll”CSComServer4.dll注册成为一个真正的COM Server, 至此, 一个基于.NETCOM Server创建完成, 任何一个COM Client都可以使用这个COM Server, 但是该COM Server还不是免注册的.

这里的/tlb开关会在demo文件夹生成一个CSComServer4.tlb文件,后面在创建C++ COM Client的时候我们会用到这个它.

 

下面, 我们创建一个C++COM Client来使用刚刚注册的COM Server:

1. 打开VS, 创建一个Win32 (VC++)工程, 命名为client, 在向导中选择控制台程序”.

2. 打开头文件stdafx.h, ”#pragma once”下面加入一行”#define _WIN32_DCOM”; 在最后一行加入” #import  "D://demo//CSComServer4.tlb" no_namespace”.

3. 打开client.cpp, 删除所有内容并插入以下代码:

#include "stdafx.h" #include <iostream> using namespace std; void InvokeComServer() { CoInitializeEx(0, COINIT_MULTITHREADED); try { ICSComServer4Ptr ptr; HRESULT hr = ptr.CreateInstance(__uuidof(CSComServer4)); if (SUCCEEDED(hr)) { cout << ptr->Version() << endl; } else { printf("0x%8x", hr); } } catch (_com_error &err) { wprintf(L"The server throws the error: %s/n", err.ErrorMessage()); wprintf(L"Description: %s/n", (PCWSTR) err.Description()); } CoUninitialize(); } int _tmain(int argc, _TCHAR* argv[]) { InvokeComServer(); char c; cin >> c; return 0; }

4. Build这个C++工程, 双击生成的client.exe, 程序输出”.NET 4.0”, 说明对COM Server的调用成功.

 

然而此时的COM Server并非免注册, 回到Visual Studio Command Prompt (2010) 窗口, 输入” regasm /u CSComServer4.dll”CSComServer4的注册信息从注册表中移除, 再次运行client.exe, 程序输出” 0x80040154”, 这个错误码表示类型未注册” (class not registered).

 

下面, 我们来创建一个真正的免注册COM Server.

1. demo文件夹创建一个txt文件, 把文件改名为CSComServer4.manifest 并输入以下内容:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

    <assemblyIdentity

        type="win32"

        name="CSComServer4"

        version="1.0.0.0"

        processorArchitecture="MSIL" />

    <clrClass

        clsid="{5E6C6A71-1AF3-4169-BE2B-3E1D6C595333}"

        progid="CSComServer4.CSComServer4"

        threadingModel="Both"

        name="CSComServer4.CSComServer4"

        runtimeVersion="v4.0.30319">

    </clrClass>

    <file name="CSComServer4.dll">

    </file>

</assembly>

2. 打开刚才创建的client工程, 在解决方案窗口, 右键点击工程 -> 选择属性’ -> 链接器(Linker) -> 清单文件(Manifest File) -> 清单依赖 (Additional Manifest Dependencies) -> 输入以下内容:

type='win32' name='CSComServer4' version='1.0.0.0' processorArchitecture='MSIL'

3. 清空client工程的输出文件夹并重新build client工程, 把生成的client.exe拷贝到demo文件.

4. 此时, demo文件夹下包含4个文件: client.exe, CSComServer4.dll, CSComServer4.manifest CSComServer4.tlb. 双击client.exe, 程序输出”.NET 4.0”, 一个简单的免注册COM创建成功!

你可能感兴趣的:(创建免注册(Registration Free)COM)