概述
- 背景
前一段时间由于业务关系,须要在一个比较旧的系统编写一个补丁。原系统使用VB编程,但如果要使用VB来实现这个补丁的内容,对于我这个并不怎么接触VB的人来说太头痛了。由于平时使用的是C#来开发,于是便想到能否用编写.NET COM组件的方式来让VB调用。想到这两三下便写了个.NET COM测试组件,用VB测试调用测试OK。接下来就是进行后续的开发,可等到开发完成后到了补丁打包环节却傻眼了。原来的补丁打包工具在诞生时还不知道.NET为何物,所以根本没有使用RegAsm来注册.NET COM组件的功能。现在更改打补丁工具那是不现实的,可要使得VB调用.NET COM又必须使用RegAsm注册,这下怎么办呢?
- 解决方式
原打包工具是支持使用RegSvr32来注册Com组件的,忽然想到能否使用RegSvr32来注册.NET COM组件呢?印象中regsvr32在注册DLL的时候会有个CallBack函数的,于是赶紧Google找找相关资料最终解决了这个问题。主要原理是写一个代理的dll,在这个DLL的注册响应函数DllRegisterServer里调用RegAsm来注册.NET COM,同理在DllUnregisterServer里反注册。
- 代理DLL代码
stdafx.h
#pragma once
#include <windows.h>
#include <tchar.h>
Register.cpp
/*----------------------------------------------
此组件主要解决C#编写的COM组件无法用RegSvr32注册的问题
原理是增加一个代理DLL,在代理DLL注册时,响应DllRegisterServer注册函数,
在响应函数中使用RegAsm来注册.Net Com组件,反注册同理。
----------------------------------------------*/
#include "stdafx.h"
#define MAX_PATH 260
//全局变量,存放注册代理dll路劲
TCHAR g_FilePath[MAX_PATH];
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
//记录代理DLL的路径,主要是为了方便后面获取代理DLL所在目录
GetModuleFileName(hModule, g_FilePath, 255);
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
//注册响应函数
extern "C" _declspec(dllexport) long DllRegisterServer(void)
{
return Register(TRUE);
}
//反注册响应函数
extern "C" _declspec(dllexport) long DllUnregisterServer(void)
{
return Register(FALSE);
}
//注册组件
//install : TRUE for install, FALSE for unstall
BOOL Register(BOOL install){
TCHAR cmd[MAX_PATH];
PROCESS_INFORMATION processInfo;
STARTUPINFO stInfo;
//获取注册命令
GetCmdLine(cmd, install);
ZeroMemory( &processInfo, sizeof(processInfo) );
ZeroMemory( &stInfo, sizeof(stInfo) );
stInfo.cb = sizeof(stInfo);
BOOL ret;
//创建注册进程
ret = CreateProcess(NULL,cmd,NULL,NULL,FALSE,CREATE_NO_WINDOW,NULL,NULL,&stInfo,&processInfo);
if(ret==TRUE){
CloseHandle(processInfo.hProcess);
CloseHandle(processInfo.hThread);
return TRUE;
}else{
//DWORD error = GetLastError();
return FALSE;
}
return FALSE;
}
//获取注册命令,加/s开关可以免除确认步骤。
//注册: RegAsm.exe /s Test.dll
//反注册:RegAsm.exe /s /u Test.dll
void GetCmdLine(LPTSTR cmd, BOOL install){
TCHAR regAsmPath[MAX_PATH];
TCHAR regDllPath[MAX_PATH];
TCHAR temp[10];
regAsmPath[0] = '