VS - regsvr32.exe的官方工程

文章目录

    • VS - regsvr32.exe的官方工程
    • 概述
    • 笔记
    • 官方原版实现
    • 自己封装一个函数来干活(注册/反注册 COM DLL)
    • END

VS - regsvr32.exe的官方工程

概述

如果是要使用COM DLL, 必须先注册。
一般手工注册就要调用regsvr32.exe xx.dll
但是控制的不够细,且一般来说,也就只能通过安装程序来注册COM DLL.
如果是一个绿色版程序集合(e.g. 解压版的程序包),启动主程序后,先判断是否能正常操作COM DLL,如果不能,则自己先在程序实现里面,将解压包内自带的COM DLL先注册一下,再使用COM DLL。

如果是这种场景的话,用系统自带的regsvr32.exe来注册COM DLL, 显然不能达到目的。
即使加 /s 参数(静默),控制的也不够细。

在看资料,里面说道,regsvr32.exe 实际上就是执行COM DLL中的导出函数(DllRegisterServer/DllUnregisterServer)来实现COM DLL的注册和反注册。

就想看一下regsvr32.exe的实现。
翻硬盘时,居然看到微软官方开源库有这个工程的源码:P
那就可以直接看源码了,不用IDA了。

工程位置 - D:\3rd_prj\vs\VCSamples\VC2008Samples\MFC\controls\regsvr
微软官方开源库地址 - https://github.com/microsoft/VCSamples.git

笔记

官方原版实现

// regsvr.cpp : Program to invoke OLE self-registration on a DLL.
//
// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Foundation Classes Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft Foundation Classes product.

#include <windows.h>
#include <ole2.h>
#include <tchar.h>
#include <malloc.h>
#include <stdio.h>
#include "resource.h"

#define FAIL_ARGS   1
#define FAIL_OLE    2
#define FAIL_LOAD   3
#define FAIL_ENTRY  4
#define FAIL_REG    5

const TCHAR _szAppName[] = _T("RegSvr32");
const char _szDllRegSvr[] = "DllRegisterServer";
const char _szDllUnregSvr[] = "DllUnregisterServer";
HINSTANCE _hInstance;

BOOL _bSilent;
BOOL _bConsole;

#define SafePutts(string) ((stdout >= 0) ? _putts(string) : 0)

void
FormatString2(
	LPTSTR lpszOut,
	int nOutSize,
	LPCTSTR lpszFormat,
	LPCTSTR lpsz1,
	LPCTSTR lpsz2
	)
{
	LPCTSTR pchSrc = lpszFormat;
	LPTSTR pchDest = lpszOut;
	while (*pchSrc != '\0') {
		if (pchSrc[0] == '%' && (pchSrc[1] >= '1' && pchSrc[1] <= '2')) {
			_tcscpy_s(pchDest, nOutSize, (LPCTSTR)(pchSrc[1] == '1' ? lpsz1 : lpsz2));
			pchDest += lstrlen(pchDest);
			pchSrc += 2;
		} else {
			if (_istlead(*pchSrc))
				*pchDest++ = *pchSrc++; // copy first of 2 bytes
			*pchDest++ = *pchSrc++;
		}
	}
	*pchDest = '\0';
}

#define MAX_STRING 1024

void
DisplayMessage(
	UINT ids,
	LPCTSTR pszArg1 = NULL,
	LPCTSTR pszArg2 = NULL,
	BOOL bUsage = FALSE,
	BOOL bInfo = FALSE
	)
{
	if (_bSilent && !_bConsole)
		return;

	TCHAR szFmt[MAX_STRING];
	LoadString(_hInstance, ids, szFmt, MAX_STRING);

	TCHAR szText[MAX_STRING];
	FormatString2(szText, MAX_STRING, szFmt, pszArg1, pszArg2);
	if (bUsage) {
		int cch = (int)_tcslen(szText);
		LoadString(_hInstance, IDS_USAGE, szText + cch, MAX_STRING - cch);
	}

	if (! _bSilent)
		MessageBox(NULL, szText, _szAppName,
			MB_TASKMODAL | (bInfo ? MB_ICONINFORMATION : MB_ICONEXCLAMATION));

	if (_bConsole) {
		TCHAR szMessage[MAX_STRING];
		FormatString2(szMessage, MAX_STRING, _T("%1: %2\n"), _szAppName, szText);
		SafePutts(szMessage);
	}
}

inline void
Usage(
	UINT ids,
	LPCTSTR pszArg1 = NULL,
	LPCTSTR pszArg2 = NULL
	)
{
	DisplayMessage(ids, pszArg1, pszArg2, TRUE);
}

inline void
Info(
	UINT ids,
	LPCTSTR pszArg1 = NULL,
	LPCTSTR pszArg2 = NULL
	)
{
	DisplayMessage(ids, pszArg1, pszArg2, FALSE, TRUE);
}

#ifdef _UNICODE
int wmain(int argc, WCHAR *argv[])
#else // !_UNICODE
int main(int argc, char *argv[])
#endif
{
	int iReturn = 0;
	HRESULT (STDAPICALLTYPE * lpDllEntryPoint)(void);

	BOOL bVisualC = FALSE;
	BOOL bUnregister = FALSE;
	LPCSTR pszDllEntryPoint = _szDllRegSvr;
	LPTSTR ptszDllEntryPoint = NULL;
	LPCTSTR pszDllName = NULL;
	LPCTSTR pszTok;
	size_t EntryPointSize = 0;

	_hInstance = ::GetModuleHandle(NULL);

	// Parse command line arguments.
	int iTok;
	for (iTok = 1; iTok < argc; iTok++) {
		pszTok = argv[iTok];

		if ((pszTok[0] == '-') || (pszTok[0] == '/')) {
			switch (pszTok[1]) {
				case 'v':
				case 'V':
					bVisualC = TRUE;
					break;

				case 's':
				case 'S':
					_bSilent = TRUE;
					break;

				case 'u':
				case 'U':
					bUnregister = TRUE;
					pszDllEntryPoint = _szDllUnregSvr;
					break;

				case 'c':
				case 'C':
					_bConsole = TRUE;
					break;

				default:
					Usage(IDS_UNRECOGNIZEDFLAG, pszTok);
					return FAIL_ARGS;
			}
		} else {
			if (pszDllName == NULL) {
				pszDllName = pszTok;
				break;
			} else {
				Usage(IDS_EXTRAARGUMENT, pszTok);
				return FAIL_ARGS;
			}
		}
	}

	if (pszDllEntryPoint != NULL) {
		EntryPointSize = (1 + strlen(pszDllEntryPoint)) * (sizeof(TCHAR));
		ptszDllEntryPoint = (TCHAR *)_malloca(EntryPointSize); // _malloca may allocate memory on the heap, so we need to call _freea to clean the heap if used
#ifdef _UNICODE
		swprintf_s(ptszDllEntryPoint, EntryPointSize, _T("%hs"), pszDllEntryPoint);
#else // !_UNICODE
		strcpy_s(ptszDllEntryPoint, EntryPointSize, pszDllEntryPoint);
#endif
	}

	if (pszDllName == NULL) {
		if (bVisualC)
			DisplayMessage(IDS_NOPROJECT);
		else
			Usage(IDS_NODLLNAME);
		_freea(ptszDllEntryPoint);
		return FAIL_ARGS;
	}

	// Initialize OLE.
	if (FAILED(OleInitialize(NULL))) {
		DisplayMessage(IDS_OLEINITFAILED);
		_freea(ptszDllEntryPoint);
		return FAIL_OLE;
	}

	SetErrorMode(SEM_FAILCRITICALERRORS);       // Make sure LoadLib fails.
	for (; iTok < argc; iTok++) {
		pszDllName = argv[iTok];

		// Load the library.
		HINSTANCE hLib = LoadLibraryEx(pszDllName, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);

		if (hLib < (HINSTANCE)HINSTANCE_ERROR) {
			TCHAR szError[12];
			_stprintf_s(szError, 12, _T("0x%08lx"), GetLastError());
			DisplayMessage(IDS_LOADLIBFAILED, pszDllName, szError);
			iReturn = FAIL_LOAD;
			goto CleanupOle;
		}

		// Find the entry point.
		(FARPROC&)lpDllEntryPoint = GetProcAddress(hLib, pszDllEntryPoint);

		if (lpDllEntryPoint == NULL) {
			TCHAR szExt[_MAX_EXT];
			_tsplitpath_s(pszDllName, NULL, 0, NULL, 0, NULL, 0, szExt, _MAX_EXT);

			if ((_tcsicmp(szExt, _T(".dll")) != 0) && (_tcsicmp(szExt, _T(".ocx")) != 0))
				DisplayMessage(IDS_NOTDLLOROCX, pszDllName, ptszDllEntryPoint);
			else
				DisplayMessage(IDS_NOENTRYPOINT, pszDllName, ptszDllEntryPoint);

			iReturn = FAIL_ENTRY;
			goto CleanupLibrary;
		}

		// Call the entry point.
		if (FAILED((*lpDllEntryPoint)())) {
			DisplayMessage(IDS_CALLFAILED, ptszDllEntryPoint, pszDllName);
			iReturn = FAIL_REG;
			goto CleanupLibrary;
		}

		Info(IDS_CALLSUCCEEDED, ptszDllEntryPoint, pszDllName);

CleanupLibrary:
		FreeLibrary(hLib);
	}

CleanupOle:
	OleUninitialize();
	_freea(ptszDllEntryPoint);
	return iReturn;
}

自己封装一个函数来干活(注册/反注册 COM DLL)

//! \file myRegsvr32.cpp
//! \brief 自己封装一个可以可以操作COM DLL注册/反注册的函数
//! \ref D:\3rd_prj\vs\VCSamples\VC2008Samples\MFC\controls\regsvr
//! \note https://github.com/microsoft/VCSamples.git

//! \note exp prj env = vs2019 vc++ unicode x64 console
 
#include <Windows.h>
#include <iostream>
#include <assert.h>

bool com_dll_Reg_or_unReg(bool isReg, const TCHAR* pszComDllPathName);

int wmain(int argc, WCHAR* argv[])
// int main(int argc, TCHAR** argv)
{
	bool b_rc = false;

	do {
		// argv[1] is COM DLL's path name
		if (2 != argc)
		{
			break;
		}

		// un register com dll
		b_rc = com_dll_Reg_or_unReg(false, argv[1]);
		assert(b_rc);

		// register com dll
		b_rc = com_dll_Reg_or_unReg(true, argv[1]);
		assert(b_rc);

	} while (false);

	return 0;
}

bool com_dll_Reg_or_unReg(bool isReg, const TCHAR* pszComDllPathName)
{
	bool b_rc = false;
	bool b_com_init_ok = false;
	HRESULT hr = S_OK;
	HINSTANCE hLib = NULL;
	HRESULT(STDAPICALLTYPE * lpDllEntryPoint)(void);

	const CHAR* pszDllRegSvr = "DllRegisterServer";
	const CHAR* pszDllUnregSvr = "DllUnregisterServer";
	const CHAR* pszComDLLApiName = NULL;

	do {
		if (NULL == pszComDllPathName)
		{
			break;
		}

		pszComDLLApiName = (isReg ? pszDllRegSvr : pszDllUnregSvr);

		hr = OleInitialize(NULL);
		if (FAILED(hr)) {
			break;
		}

		b_com_init_ok = true;
		SetErrorMode(SEM_FAILCRITICALERRORS); // Make sure LoadLib fails.

		// Load the library.
		hLib = LoadLibraryEx(pszComDllPathName, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
		if (hLib < (HINSTANCE)HINSTANCE_ERROR) {
			break;
		}

		(FARPROC&)lpDllEntryPoint = GetProcAddress(hLib, pszComDLLApiName);
		if (NULL == lpDllEntryPoint) {
			break;
		}

		hr = (*lpDllEntryPoint)();
		if (FAILED(hr)) {
			break;
		}

		b_rc = true;
	} while (false);

	if (NULL != hLib)
	{
		FreeLibrary(hLib);
		hLib = NULL;
	}
	
	if (b_com_init_ok)
	{
		b_com_init_ok = false;
		OleUninitialize();
	}

	return b_rc;
}

END

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/713660.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【原创】springboot+mysql小区用水监控管理系统设计与实现

个人主页&#xff1a;程序猿小小杨 个人简介&#xff1a;从事开发多年&#xff0c;Java、Php、Python、前端开发均有涉猎 博客内容&#xff1a;Java项目实战、项目演示、技术分享 文末有作者名片&#xff0c;希望和大家一起共同进步&#xff0c;你只管努力&#xff0c;剩下的交…

C++ 45 之 赋值运算符的重载

#include <iostream> #include <string> #include <cstring> using namespace std;class Students05{ public:int m_age;char* m_name;Students05(){}Students05(const char* name,int age){// 申请堆空间保存m_name;this->m_name new char[strlen(name)…

Kotlin 语言基础学习

什么是Kotlin ? Kotiln翻译为中文是:靠他灵。它是由JetBrains 这家公司开发的,JetBrains 是一家编译器软件起家的,例如常用的WebStorm、IntelliJ IDEA等软件。 Kotlin官网 JetBrains 官网 Kotlin 语言目前的现状: 目前Android 已将Kotlin 作为官方开发语言。 Spring 框…

应急响应 | 基本技能 | 01-系统排查

系统排查 目录 系统基本信息 Windows系统Linux系统 用户信息 Windows系统 1、命令行方式2、图形界面方法3、注册表方法4、wmic方法 Linux系统 查看所有用户信息分析超级权限账户查看可登录的用户查看用户错误的登录信息查看所有用户最后的登录信息查看用户最近登录信息查看当…

快速上手SpringBoot

黑马程序员Spring Boot2 文章目录 1、SpringBoot 入门程序开发1.1 创建一个新的项目 2、浅谈入门程序工作原理2.1 parent2.2 starter2.3 引导类2.4 内嵌tomcat 1、SpringBoot 入门程序开发 1.1 创建一个新的项目 file > new > project > empty Project 创建新模块&a…

ubuntu20.04桌面蓝屏问题解决

前些天做仿真项目&#xff0c;遇到了ubuntu蓝屏问题&#xff0c;于是想着找几个参考办法修复&#xff0c;但不管用&#xff0c;疑似是重要组件损坏。 损坏的原因是强制关机&#xff0c;但究竟是强制关了哪一个卡死的进程&#xff0c;不得而知&#xff0c;我有一个关不掉的仿真…

Waf 绕过手法测试

设备类型 由上到下,waf的检测细腻度依次降低 网络层WAF&#xff1a;先拦截流量&#xff0c;进行检测后再转发给 应用层WAF&#xff1a;先经过apache/nginx解析后再交给php处理 云 WAF&#xff08;CDNWAF&#xff09;&#xff1a;简单的看成CDN加上软件WAF的结合体&#xff0c…

vue格网图

先看效果 再看代码 <n-gridv-elsex-gap"20":y-gap"20"cols"2 s:2 m:3 l:3 xl:3 2xl:4"responsive"screen" ><n-grid-itemv-for"(item,index) in newSongList":key"item.id"class"cursor-pointer …

Spring底层架构核心概念解析

BeanDefinition BeanDefinition表示Bean定义,BeanDefinition中存在很多属性用来描述一个Bean的特点.比如: beanClass:表示Bean类型scope:表示Bean作用域,单例/原型等lazyInit:表示Bean是否懒加载initMethodName:表示Bean初始化时要执行的方法destoryMethodName:表示Bean销毁时…

文章解读与仿真程序复现思路——电工技术学报EI\CSCD\北大核心《计及台风时空特性和灵活性资源协同优化的配电网弹性提升策略》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

SpringBootWeb 篇-入门了解 Spring Cache 、Spring Task 与 WebSocket 框架

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 Spring Cache 概述 1.1 Spring Cache 具体使用 1.1.1 引入依赖 1.1.2 Spring Cache 相关注解的介绍 2.0 Spring Task 概述 2.1 cron 表达式 2.2 Spring Task 使用…

程序猿大战Python——函数——拆包和交换变量值与引用

拆包 目标&#xff1a;了解拆包的使用。 先来看看在现实生活中的拆包。比如&#xff0c;张同学背着背包来教室上课后&#xff0c;需要从背包中拿出电脑、鼠标、数据线、电源线等&#xff0c;这个过程就是拆包! 接着&#xff0c;看一下在Python程序中的拆包&#xff1a;把组合形…

基于单片机和GP2Y1010AU粉尘传感器的空气质量检测仪设计

摘要 随着社会的发展,随着工业的发展,其给人们的生活带来很多便利。然而,工业生产过程中会产生很多对人体有害的因素,比如煤炭开采、水泥生产等行业中的粉尘污染。其在各种危害因素中对人体健康的影响最为严重。粉尘对人体的危害最直接、最严重的是引起尘肺病。当粉尘浓度过…

云原生技术实现Devops自动化运维

云原生技术实现Devops自动化运维 随着云计算和DevOps理念的普及&#xff0c;云原生技术在自动化运维中的应用日益广泛。本文将探讨云原生技术如何通过容器化、微服务架构、CI/CD流水线等手段&#xff0c;提升DevOps自动化运维的效率和灵活性&#xff0c;并通过案例分析具体应用…

Day01_Ajax入门

文章目录 学习目标一、AJAX 概念和 axios 使用1. 目标2. 讲解2.1 什么是 AJAX ?2.2 什么是服务器&#xff1f;2.3 为何学 AJAX ?2.4 怎么学 AJAX ?2.5 例子2.6 axios语法 二、认识 URL1. 目标2. 讲解2.1 为什么要认识 URL ?2.2 什么是 URL &#xff1f;2.3 URL的组成 &…

架构设计 - WEB项目的基础序列化配置

摘要&#xff1a;web项目中做好基础架构(redis&#xff0c;json)的序列化配置有重要意义 支持复杂数据结构&#xff1a;Redis 支持多种不同的数据结构&#xff0c;如字符串、哈希表、列表、集合和有序集合。在将这些数据结构存储到 Redis 中时&#xff0c;需要将其序列化为字节…

IT入门知识博客文章大纲(0/10)

IT入门知识博客文章大纲 引言 什么是IT&#xff1f; 信息技术&#xff08;Information Technology&#xff09;&#xff0c;互联网技术是指在计算机技术的基础上开发建立的一种信息技术 。互联网技术通过计算机网络的广域网使不同的设备相互连接&#xff0c;加快信息的传输速度…

【JavaEE精炼宝库】多线程(6)线程池

目录 一、线程池的概念及优势 1.1 线程池的概念&#xff1a; 1.2 线程池的优势&#xff1a; 二、工厂模式 三、标准库中的线程池 3.1 标准库线程池参数解释&#xff1a; 3.1.1 corePoolSize | maximumPoolSize&#xff1a; 3.1.2 keepAliveTime | unit&#xff1a; 3.1…

Vue50-mixin混入

一、为什么要使用 mixin混入 两个组件共享一个配置。 二、使用 mixin混入 2-1、创建一个混合js文件 2-2、引入混合js文件 1、局部混合 在每个组件中都引入混合js文件 注意&#xff1a; 混合就是复用配置&#xff0c;vm实例中的所有的配置项&#xff0c;都能在混合.js文件中写…