利用RegSvr32来注册.NET COM组件

转载 2015年07月07日 14:14:47
  • 背景

  前一段时间由于业务关系,须要在一个比较旧的系统编写一个补丁。原系统使用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] = '\0';
regDllPath[0] = '\0';
temp[0] = '\0';

GetRegAsmPath(regAsmPath); //获取RegAsm.exe程序绝对路径
GetRegDllPath(regDllPath); //获取需要注册的.NET COM组件绝对路径

if(install){
lstrcpy(temp, _T(" /s "));
}else{
lstrcpy(temp, _T(" /s /u "));
}

cmd[0] = '\0';
lstrcat(cmd, regAsmPath);
lstrcat(cmd, temp);
lstrcat(cmd, regDllPath);
}

//获取需要注册 .Net Com 组件路径,此处写死为Test.dll,与代理dll在同一个目录
//后期可以改成读取ini配置文件
void GetRegDllPath(LPTSTR path){
int count = 0;
for(int i=0; i < MAX_PATH; i++){
if(g_FilePath[i] == _T('\\')){
count = i + 2;
}
}

TCHAR temp[MAX_PATH];
lstrcpyn(temp, g_FilePath, count); //代理DLL所在目录
lstrcat (path, _T("\""));
lstrcat (path, temp);
lstrcat (path, _T("Test.dll\""));
}

//获取 .NET COM 注册程序 RegAsm.exe 的路径
//方法:读取[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\InstallRoot]的值,
//然后拼接上"v2.0.50727\RegAsm.exe"
void GetRegAsmPath(LPTSTR path){
HKEY hKey;
DWORD dwBufLen = MAX_PATH;
LONG lRet;

lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,_T("SOFTWARE\\Microsoft\\.NETFramework"),0, KEY_READ, &hKey);
lRet = RegQueryValueEx(hKey, _T("InstallRoot"), NULL, NULL, (LPBYTE)path, &dwBufLen);

RegCloseKey(hKey);

lstrcat(path, _T("v2.0.50727\\RegAsm.exe"));
}
复制代码

java 调用windows的COM组件举例(使用JACOB)

最近公司需要做一个效果,开发一个程序能在程序运行时打开microsoft office的相关软件,实时写入,然后能关闭,你能看到数据写入的效果。如下图:发现用java写程序的话需要通过JACOB来调用...
  • zp357252539
  • zp357252539
  • 2016年06月04日 23:24
  • 5717

COM组件与.Net组件的比较

1、COM组件与.Net组件的比较        COM技术要早于.Net技术。COM定义了一个组件模型,在该模型中,组件可以使用不同的编程语言进行编写,其可以在本地进程中使用,也可以跨进程使用或...
  • Chinamming
  • Chinamming
  • 2013年11月21日 13:47
  • 3468

【VS开发】这就是COM组件

[实例]这就是COM组件 时间 2012-02-21 10:49:15  CSDN博客 原文  http://blog.csdn.net/btwsmile/article/details/72...
  • LG1259156776
  • LG1259156776
  • 2016年04月09日 21:42
  • 2374

利用RegSvr32来注册.NET COM组件

·        背景   前一段时间由于业务关系,须要在一个比较旧的系统编写一个补丁。原系统使用VB编程,但如果要使用VB来实现这个补丁的内容,对于我这个并不怎么接触VB的人来说太头痛了。由于...
  • meteorwing
  • meteorwing
  • 2015年03月02日 13:05
  • 275

ShellExecute执行regsvr32.exe注册com控件到系统目录下

思路:把exe中dll资源导出到系统目录文件夹下     一般32位系统放到system32下,64位系统将32位的放到sysWOW64下,64位控件放到system32下。 //Registry...
  • qq_21794823
  • qq_21794823
  • 2017年03月30日 15:35
  • 920

Regsvr32(windows注册/卸载组件)的使用方法详细说明

Regsvr32(windows注册/卸载组件)的使用方法详细说明   Regsvr32是一个Windows系统的内嵌程序,不仅存在于Windows2000 / XP下,同时也能在Window...
  • haizhongyun
  • haizhongyun
  • 2012年05月10日 10:44
  • 5480

regsvr32 注册 ocx 时卡死,不退出

今天在将一个 vs2010 写的 exe 工程改造为 ocx 时,前期一切顺利,也能编译通过(不过在最后生成 .ocx 时 vs 一直卡着不动,先暂且不管,通过 Build --> Cancel 强制...
  • wangchao1988ok
  • wangchao1988ok
  • 2015年06月16日 14:14
  • 1657

Regsvr32注册DLL和Regasm

在网上搜索关于为什么要使用Regsvr32注册DLL。 得到下面的回答,感觉蛮好的。所以记录下来。感觉就好像指针一样。普通DLL是不用注册嘀. 只有com组件才需要注册,注册时他把clsid和pr...
  • qq_30122639
  • qq_30122639
  • 2016年12月15日 14:06
  • 1085

regsvr32.exe文件注册

Regsvr32命令修复系统故障实例使用过activex的人都知道,activex不注册是不能够被系统识别和使用的,一般安装程序都会自动地把它所使用的activex控件注册,但如果你拿到的一个控件需要...
  • chenyujing1234
  • chenyujing1234
  • 2012年03月22日 10:48
  • 4657

C# DLL库自动注册的两种方法(调用Regsvr32法、调用DllRegisterServer函数法)

本文将为大家讲述DLL库自动注册的两种方法,包括调用Regsvr32方法等。希望通过本文能对大家有所帮助。  首先,大家都知道在Windows的“运行”中,输入“Regsvr32.exe 路径”这样的...
  • missxin
  • missxin
  • 2011年07月19日 15:32
  • 1895
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:利用RegSvr32来注册.NET COM组件
举报原因:
原因补充:

(最多只允许输入30个字)