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    5const 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 1024void
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 _UNICODEswprintf_s(ptszDllEntryPoint, EntryPointSize, _T("%hs"), pszDllEntryPoint);
#else // !_UNICODEstrcpy_s(ptszDllEntryPoint, EntryPointSize, pszDllEntryPoint);
#endif}if (pszDllName == NULL) {if (bVisualC)DisplayMessage(IDS_NOPROJECT);elseUsage(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);elseDisplayMessage(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 nameif (2 != argc){break;}// un register com dllb_rc = com_dll_Reg_or_unReg(false, argv[1]);assert(b_rc);// register com dllb_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.mzph.cn/diannao/28276.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring学习笔记(九)简单的SSM框架整合

实验目的 掌握SSM框架整合。 实验环境 硬件&#xff1a;PC机 操作系统&#xff1a;Windows 开发工具&#xff1a;idea 实验内容 整合SSM框架。 实验步骤 搭建SSM环境&#xff1a;构建web项目&#xff0c;导入需要的jar包&#xff0c;通过单元测试测试各层框架搭建的正确…

IDEA 设置主题、背景图片、背景颜色

一、设置主题 1、点击菜单 File -> Settings : 点击 Settings 菜单 2、点击 Editor -> Color Scheme -> Scheme, 小哈的 IDEA 版本号为 2022.2.3 , 官方默认提供了 4 种主题&#xff1a; Classic Light &#xff08;经典白&#xff09; ;Darcula &#xff08;暗黑主…

知识普及:什么是边缘计算(Edge Computing)?

边缘计算是一种分布式计算架构&#xff0c;它将数据处理、存储和服务功能移近数据产生的边缘位置&#xff0c;即接近数据源和用户的位置&#xff0c;而不是依赖中心化的数据中心或云计算平台。边缘计算的核心思想是在靠近终端设备的位置进行数据处理&#xff0c;以降低延迟、减…

React组件通信方式总结

文章目录 父组件向子组件传递数据子组件向父组件传递数据兄弟组件传递数据祖先与后代组件之间的传值复杂关系的组件之间的传值使用发布-订阅模式使用 Redux 父组件向子组件传递数据 无论是类组件还是函数式组件&#xff0c;父组件向子组件传递数据的方式都是使用 props 来实现…

vue怎样获取dom元素?

在 Vue.js 中&#xff0c;直接操作 DOM 元素通常不是推荐的做法&#xff0c;因为 Vue 的核心思想是数据驱动视图&#xff0c;我们更倾向于通过改变数据来影响视图&#xff0c;而不是直接操作 DOM。 然而&#xff0c;在某些情况下&#xff0c;你可能确实需要直接获取和操作 DOM…

C++模板之模板成员函数不能偏特化

目录 1.引言 2.类模板成员函数的特化 2.1.没有函数特化的类模板 2.2.增加函数特化 3.“曲线救国”函数“偏特化” 3.1.函数重载实现“偏特化” 3.2.使用类型选择机制实现“偏特化” 4.总结 1.引言 C 泛型编程的资料在介绍类模板的特化和偏特化的时候&#xff0…

【HarmonyOS】HUAWEI DevEco Studio 下载地址汇总

目录 OpenHarmony 4.x Releases 4.1 Release4.0 Release OpenHarmony 3.x Releases 3.2.1 Release3.2 Release3.1.3 Release3.1.2 Release3.1.1 Release3.1 Release 说明 Full SDK&#xff1a;面向OEM厂商提供&#xff0c;包含了需要使用系统权限的系统接口。 Public SDK&am…

Python对Excel表格的操作

今天, 实现了一个对excel表格操作的技术方案. 操作的要求是: (1)在一个目标表格(表格2)中的第2列已经有唯一标识码.第1列为凭证号, 但是是空的. (2)在数据表格中(表格1)中有资产的信息, 其中第2列是资产的唯一标识码, 第1列是凭证号. (3)表格2内只有部分资产. 要求: 从表格1中…

前端:鼠标点击实现高亮特效

一、实现思路 获取鼠标点击位置 通过鼠标点击位置设置高亮裁剪动画 二、效果展示 三、按钮组件代码 <template><buttonclass"blueBut"click"clickHandler":style"{backgroundColor: clickBut ? rgb(31, 67, 117) : rgb(128, 128, 128),…

C# OpenCvSharp 图像处理函数-图像拼接-hconcat、vconcat、Stitcher

在图像处理和计算机视觉领域,图像拼接是一个常见的操作。OpenCvSharp是一个用于.NET平台的OpenCV封装库,可以方便地进行图像处理。本文将详细介绍如何使用OpenCvSharp中的hconcat、vconcat函数以及Stitcher类进行图像拼接,并通过具体示例帮助读者理解和掌握这些知识点。 函…

Java生成NetCDF文件

因为需要再Cesium中实现风场粒子效果&#xff0c;网上找了许多项目&#xff0c;大多是通过加载NC文件来进行渲染的&#xff0c;因此了解NC文件又成了一件重要的事。特此记录用java成果生成可在前端渲染&#xff0c;QGIS中正常渲染的NetCDF文件的相关代码&#xff08;有没详细整…

16. 第十六章 类和函数

16. 类和函数 现在我们已经知道如何创建新的类型, 下一步是编写接收用户定义的对象作为参数或者将其当作结果用户定义的函数. 本章我会展示函数式编程风格, 以及两个新的程序开发计划.本章的代码示例可以从↓下载. https://github.com/AllenDowney/ThinkPython2/blob/master/c…

java程序在运行过程各个内部结构的作用

一&#xff1a;内部结构 一个进程对应一个jvm实例&#xff0c;一个运行时数据区&#xff0c;又包含多个线程&#xff0c;这些线程共享了方法区和堆&#xff0c;每个线程包含了程序计数器、本地方法栈和虚拟机栈接下来我们通过一个示意图介绍一下这个空间。 如图所示,当一个hell…

内窥镜系统设计简介

内窥镜系统设计简介 1. 源由2. 系统组成2.1 光学系统2.2 机械结构2.3 电子系统2.4 软件系统2.5 安全性和合规性2.6 研发与测试2.7 用户培训与支持 3. 研发过程3.1 光学系统Step 1&#xff1a;镜头设计Step 2&#xff1a;光源Step 3&#xff1a;成像传感器 3.2 机械结构Step 1&a…

11.泛型、trait和生命周期(上)

标题 一、泛型数据的引入二、改写为泛型函数三、结构体/枚举中的泛型定义四、方法定义中的泛型 一、泛型数据的引入 下面是两个函数&#xff0c;分别用来取得整型和符号型vector中的最大值 use std::fs::File;fn get_max_float_value_from_vector(src: &[f64]) -> f64…

代码随想录-Day31

455. 分发饼干 假设你是一位很棒的家长&#xff0c;想要给你的孩子们一些小饼干。但是&#xff0c;每个孩子最多只能给一块饼干。 对每个孩子 i&#xff0c;都有一个胃口值 g[i]&#xff0c;这是能让孩子们满足胃口的饼干的最小尺寸&#xff1b;并且每块饼干 j&#xff0c;都…

Python中的命名空间和作用域:解密变量的可见性和生命周期

在 Python 中&#xff0c;命名空间&#xff08;Namespace&#xff09;和作用域&#xff08;Scope&#xff09;是重要的概念&#xff0c;它们决定了变量和函数的可见性和生命周期。理解命名空间和作用域是编写高效、可维护代码的关键。 基本语法 命名空间 命名空间是一个存储…

新视野大学英语2 词组 6.16

decide between rival options 在互相竞争的选项中做出选择 chinese imperial general 中国帝国将军 on a raid into enemy territory 深入敌方领土突袭 on a raid into&#xff1a;“在进入……的突袭行动中”。 通常指军事行动中快速、秘密地侵入敌人控制的区域&#xff0c…

oracle打补丁

1.备份 su - grid -c "crsctl status res -t" cat /proc/meminfo | grep HugePagesls -lrt /dev/ls -lrt /dev/sd*ls -lrt /dev/asm*cat /etc/udev/rules.d/asm***df -hmountfree -g/etc/security/limits.conf/etc/hosts/etc/selinux/config /etc/pam.d/system-aut…

vs+qt5.0 使用poppler 操作库

Poppler 是一个用来生成 PDF 的C类库&#xff0c;从xpdf 继承而来。vs编译库如下&#xff1a; vs中只需要添加依赖库即可 头文件&#xff1a;