Com 组件的装载和卸载

delphi实现COM组件的自动注册与卸载 delphi实现COM组件的自动注册与卸载,源码实现加详解。 立即下载

转自http://www.cnblogs.com/zcgao/archive/2011/07/18/2109220.html

进程内组件的装载: 



客户程序调用COM 库的 CoCreateInstance 或 CoGetClassObject 函数创建 COM 对象,在 CoGetClassObject 函数中,COM 库根据系统注册表中的信息,找到类标识符 CLSID 对应的组件程序(DLL 文件)的全路径,然后调用 LoadLibrary(实际上是 CoLoadLibrary)函数,并调用组件程序的 DllGetClassObject 引出函数。DllGetClassObject 函数创建相应的类厂对象,并返回类厂对象的 IClassFactory 接口。至此 CoGetClassObject 函数的任务完成,然后客户程序或者 CoCreateInstance 函数继续调用类厂对象的 CreateInstance 成员函数,由它负责 COM 对象的创建工作。 



CoCreateInstance 

|-CoGetClassObject 

|-Get CLSID -> DLLfile path 

|-CoLoadLibrary 

|-DLLfile.DllGetClassObject 

|-return IClassFactory 

|-IClassFactory.CreateInstnace 



进程外组件的装载: 



在 COM 库的 CoGetClassObject 函数中,当它发现组件程序是 EXE 文件(由注册表组件对象信息中的 LocalServer 或 LocalServer32 值指定)时,COM 库创建一个进程启动组件程序,并带上“/Embedding”命令行参数,然后等待组件程序;而组件程序在启动后,当它检查到“/Embedding”命 令行参数后,就会创建类厂对象,然后调用 CoRegisterClassObject 函数把类厂对象注册到 COM 中。当 COM 库检查到组件对象的类厂之后,CoGetClassObject 函数就把类厂对象返回。由于类厂与客户程序运行在不同的进程中,所以客户程序得到的是类厂的代理对象。一旦客户程序或 COM 库得到了类厂对象,它就可以完成组件对象的创建工作。 

进程内对象和进程外对象的不同创建过程仅仅影响了 CoGetClassObject 函数的实现过程,对于客户程序来说是完全透明的。 



CoGetClassObject 

|-LocalServer/LocalServer32 

|-Execute EXE /Embedding 

|-Create class factory 

|-CoRegisterClassObject ( class factory ) 

|-return class factory (proxy) 



进程内组件的卸载: 



只有当组件程序满足了两个条件时,它才能被卸载,这两个条件是:组件中对象数为 0,类厂的锁计数为 0。满足这两个条件时,DllCanUnloadNow 引出函数返回 TRUE。COM 提供了一个函数 CoFreeUnusedLibraries,它会检测当前进程中的所有组件程序,当发现某个组件程序的 DllCanUnloadNow 函数返回 TRUE 时,就调用 FreeLibrary 函数(实际上是 CoFreeLibrary 函数)把该组件从程序从内存中卸出。 

该由谁来调用 CoFreeUnusedLibraries 函数呢?因为在组件程序执行过程中,它不可能把自己从内存中卸出,所以这个任务应该由客户来完成。客户程序随时都可以调用 CoFreeUnusedLibraries 函数完成卸出工作,但通常的做法是,在程序的空闲处理过程中调用 CoFreeUnusedLibraries 函数,这样做既可以避免程序中处处考虑对 CoFreeUnusedLibraries 函数的调用,又可以使不再使用的组件程序得到及时清除,提高资源的利用率,COM 规范也推荐这种做法。 



进程外组件的卸载: 



进程外组件的卸载比较简单,因为组件程序运行在单独的进程中,一旦其退出的条件满足,它只要从进程的主控函数返回即可。在 Windows 系统中,进程的主控函数为 WinMain。 

前面曾经说过,在组件程序启动运行时,它调用 CoRegisterClassObject 函数,把类厂对象注册到 COM 中,注册之后,类厂对象的引用计数始终大于 0,因此单凭类厂对象的引用计数无法控制进程的生存期,这也是引入类厂对象的加锁和减锁操作的原因。进程外组件的载条件与 DllCanUnloadNow 中的判断类似,也需要判断 COM 对象是否还存在、以及判断是否锁计数器为 0,只有当条件满足了,进程的主函数才可以退出。 
从原则上讲,进程外组件程序的卸载就是这么简单,但实际上情况可能复杂一些,因为有些组件程序在运行过程中可以创建自己的对象,或者包含用户界面的程序在 运行过程中,用户手工关闭了进程,那么进程对这些动作的处理要复杂一些。例如,组件程序在运行过程中,用户又打开了一个文件并进行操作,那么即使原先创建 的对象被释放了,而且锁计数器也为 0,进程也不能退出,它必须继续为用户服务,就像是用户打开的进程一样。对这种程序,可以增加一个“用户控制”标记 flag,如果 flag 为 FALSE,则可以按简单的方法直接退出程序即可;如果 flag 为 TRUE,则表明用户参与了控制,组件进程不能马上退出,但应该调用 CoRevokeClassObject 函数以便与 CoRegisterClassObject 调用相响呼应,把进程留给用户继续进行。 

如果组件程序在运行过程中,用户要关闭进程,而此时并不满足进程退出条件,那么进程可以采取两种办法:第一种方法,把应用隐藏起来,并把 flag 标记设置为 FALSE,然后组件程序继续运行直到卸载条件满足为止;另一种办法是,调用 CoDisconnectObject 函数,强迫脱离对象与客户之间的关系,并强行终止进程,这种方法比较粗暴,不提倡采用,但不得已时可以也使用,以保证系统完成一些高优先级的操作。 



------------------------------------------------------------------------------- 

COM 库常用函数 

------------------------------------------------------------------------------- 

初始化函数 CoBuildVersion 获得 COM 库的版本号 

CoInitialize COM 库初始化 

CoUninitialize COM 库功能服务终止 

CoFreeUnusedLibraries 释放进程中所有不再使用的组件程序 

GUID 相关函数 IsEqualGUID 判断两个 GUID 是否相等 

IsEqualIID 判断两个 IID 是否相等 

IsEqualCLSID 判断两个 CLSID 是否相等 (*为什么要3个函数) 

CLSIDFromProgID 字符串组件标识转换为 CLSID 形式 

StringFromCLSID CLSID 形式标识转化为字符串形式 

IIDFromString 字符串转换为 IID 形式 

StringFromIID IID 形式转换为字符串 

StringFromGUID2 GUID 形式转换为字符串(*为什么有 2) 

对象创建函数 CoGetClassObject 获取类厂对象 

CoCreateInstance 创建 COM 对象 

CoCreateInstanceEx 创建 COM 对象,可指定多个接口或远程对象 

CoRegisterClassObject 登记一个对象,使其它应用程序可以连接到它 

CoRevokeClassObject 取消对象的登记 

CoDisconnectObject 断开其它应用与对象的连接 

内存管理函数 CoTaskMemAlloc 内存分配函数 

CoTaskMemRealloc 内存重新分配函数 

CoTaskMemFree 内存释放函数 

CoGetMalloc 获取 COM 库内存管理器接口 



------------------------------------------------------------------------------- 

HRESULT 类型 

------------------------------------------------------------------------------- 

大多数 COM 函数以及一些接口成员函数的返回值类型均为 HRESULT 类型。HRESULT 类型的返回值反映了函数中的一些情况,其类型定义规范如下: 



31 30 29 28 16 15 0 

|-----|--|------------------------|-----------------------------------| 



类别码 (30-31) 反映函数调用结果: 

00 调用成功 

01 包含一些信息 

10 警告 

11 错误 

自定义标记(29) 反映结果是否为自定义标识,1 为是,0 则不是;

4G LTE 与 5G 无线网络规划对比:从 BBU/RRU 到 CU/DU/AAU 的架构演进解析 本文深度解析4G LTE与5G无线网络架构的演进差异,从BBU/RRU分立式架构到CU/DU/AAU三级重构,揭示移动通信代际跃迁的技术本质。重点对比了网络规划中的覆盖能力、容量规划、传输网络等九大维度,为通信工程师提供实用的技术对照手册,助力5G网络高效部署。 阅读详情

相关推荐

从标准到实战:详解IEC 61000-4-2下的ESD电路防护设计

本文深入解析IEC 61000-4-2标准下的ESD电路防护设计,从静电防护的基础原理到实战应用。详细介绍了接触放电与空气放电的区别、防护器件选型要点(如TVS管和压敏电阻)以及PCB布局的黄金法则,帮助工程师有效提升电子产品的抗静电能力,确保设备在严苛环境下的稳定运行。

weixin_33704234的博客 512

COM学习(二)——COM的注册和卸载

COM组件是跨语言的,组件被注册到注册表中,在加载时由加载函数在注册表中查找到对应模块的路径并进行相关加载。它的存储规则如下: 1. 在注册表的HKEY_CLASSES_ROOT中以模块名的方式保存着COM模块的GUID,比如HKEY_CLASSES_ROOT\ADODB.Error\CLSID键中保存着模块ADODB.Error的GUID为{00000541-0000-0010-8000-00A

Masimaro的专栏 2202

七、从0开始卷出一个新项目之瑞萨RZN2L 2.2.2 启动模式和flash

七、从0开始卷出一个新项目之瑞萨RZN2L 2.2.2 启动模式和flash。

cl234583745的博客 1466

COM组件的注册和卸载

2、进程外注册,即所需注册的是exe(注意反斜杠一定要加上)卸载:regsvr32 /u 【dll全路径】卸载:【exe的全路径】 /unregister。【exe的全路径】 /regserver。1、进程内注册,即所需要注册的是DLL。regsvr32 【dll全路径】

notfindjob的博客 1082

别再凭感觉了!手把手教你用Excel搞定激光器MPE与NOHD安全计算(附模板下载)

本文详细介绍了如何利用Excel自动化计算激光器的MPE(最大允许照射量)和NOHD(标称眼危害距离),提升激光安全评估的效率和准确性。通过实战案例和模板下载,帮助工程师快速掌握GB/T 7247标准中的关键计算,避免常见错误,适用于激光测距仪等设备的安评工作。

weixin_30954265的博客 468

利用DRONEKIT-SITL + MAVPROXY + QGroundControl模拟飞行

dronekit: 一种用于无人机控制的python库。 dronekit-sitl:一种本地仿真工具,相当于本地虚拟化了一个无人机。 mavproxy:数据转发软件(类似于插线板的感觉,一个输入,多个相同的输出)。打开一个Anaconda prompt 首先激活相应的环境 然后运行如下命令: 保持2中的Anaconda prompt处于运行状态,另打开一个Anaconda prompt窗口,运行如下命令: tcp:127.0.0.1:5760: SITL默认端口,作为mavproxy的输入,把输入数据转发

Done___的博客 4344

com组件注册与卸载

  老潘说:   COM规范中规定:支持自注册的进程外组件,必需支持两个命令行参数:     /RegServer和/UnRegServer,以便完成注册或注销操作.   进程内用:regsvr32 .dll文件 regsvr32 /u .ocx文件

xzmyzy的专栏 4882

固定资产报废的损失鉴定怎么做?

在社会生产的日常中,企业经常会遇到固定资产报废的损失鉴定,那么怎么去做鉴定?哪些情况下能申请固定资产报废损失鉴定呢? 今天,华碧鉴定就和大家说一说固定资产报废损失鉴定那些事儿。 符合下列条件之一的固定资产可申请报废: 1、使用年限过长,功能丧失,完全失去使用价值,或不能使用并无修复价值的; 2、产品技术落后,质量差,耗能高,效率低,已属淘汰且不适于继续使用,或技术指标已达不到使用要求的; 3、严重损坏,无法修复的或虽能修复,但累计修理费已接近或超过市场价值的; 4、主要附件损坏,无.

weixin_50362670的博客 2116

com+组件的注册,卸载和管理

com+组件的注册,卸载和管理

yrryyff的博客 3392

【MuJoCo】第一章 仿真环境的搭建与入门

它通过优化的接触动力学算法,能够高效处理复杂的多体交互,这使其成为从机械臂操控到足式机器人运动,再到大规模强化学习训练的理想选择。特别是与 JAX 集成的 MJX 的推出,将高性能仿真的边界推向了新的高度,使得在单台机器上并行数千个仿真环境成为可能。我们将通过编写您的第一个仿真程序,逐步拆解 MuJoCo 的工作流,让您亲手感受物理引擎的脉动。这种加速能力对于需要海量仿真样本的强化学习算法(如 PPO)是颠覆性的,它将原本需要数小时的训练缩短到几分钟。上的几何形状,用于碰撞检测和可视化。

u012133341的博客 368

数仓解惑:数据仓库常见建模方法与大数据领域建模实例综述

为什么需要数据建模? 为什么要进行数据仓库建模? 随着DT时代互联网、智能设备等信息技术的发展,数据开始井喷式的增长,如何讲这些数据进行有序、有结构地分类组织存储是我们面临的一个挑战。 如果把数据看作图书馆里的书,我们希望看到它们在书架上分门别类地放置,而不是乱糟糟的 大数据的数仓建模是通过建模的方法更好的组织、存储数据,以便在 性能、成本、效率和数据质量之间找到最佳平衡点。一般主要从下面四点考虑 ...

云祁QI 5850

Com 组件的装载和卸载 .

进程内组件的装载: 客户程序调用COM 库的 CoCreateInstance 或 CoGetClassObject 函数创建 COM 对象,在 CoGetClassObject 函数中,COM 库根据系统注册表中的信息,找到类标识符 CLSID 对应的组件程序(

MOKA 759

修复漏洞Windows 2012 Server R2(CVE-2016-2183)、(CVE-2015-2808)、(CVE-2013-2566)

【代码】修复漏洞Windows 2012 Server R2(CVE-2016-2183)、(CVE-2015-2808)、(CVE-2013-2566)

路~可以走过 2773

COM第三部分(类厂、对象的创建、组件程序装载卸载以及生存期、COM组件与客户程序交互过程的描述)

一、类厂: 作用: COM库通过类厂来创建对象,每个COM类对应着有一个COM类厂来创建此COM类的对象。 并不是用户直接通过c++的new来实例化 优点: 使用类厂来创建对象,可以将所有客户创建的对象的接口统一(统一的方法创建不同类型的COM对象),实现位置透明 说明: 类厂本身也是一个COM对象,当然,类厂不需要其他的类厂创建了; 类厂有一个特殊的接口IClassFactory,该接口派生自I...

KingOfMyHeart的博客 572

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

COM原理

组件程序的装载和卸载 ------------------------------------------------------------------------------- 进程内组件的装载: 客户程序调用COM 库的 CoCreateInstance 或 CoGetClassObject 函数创建 COM 对象,在 CoGetClassObject 函数中,COM 库根据系统注册表中的信...

weixin_30732825的博客 128

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

COM学习....

COM初始化if (CoInitialize(NULL) != S_OK) {return 1;}CoUninitialize();COM库的内存管理由于COM组件与客户程序,COM库三者之间内存交互(分配和释放可能不在同一个模块),所以必须使用一致的内在管理器。COM提供的内在管理器标准:class IMalloc:public IUnknow{    void*    Al

WLV的专栏 945

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

COM组件开发知识重点

第1章 概述    COM组件可以是一个Dll(进程内组件),也可以是一个EXE(进程外组件)。进程内组件就是组件和客户程序在同一进程内,进程外组件即组件和客户程序分别有自己的进程空间。    一个COM组件可以包含多个COM对象,一个COM对象又可以有多个接口。   第2章 COM对象和接口 2.1 CLSID和IID     对于COM对象来说,接口是它与外界进行交互的唯一途径。

wangjichang1的专栏 1079

动态库的装载与卸载

相关的三个函数: (LoadLibrary,GetProcAddress,FreeLibrary) 动态载入 DLL 动态载入方式是指在编译之前并不知道将会调用哪些 DLL 函数, 完全是在运行过程中根据需要决定应调用哪些函数。 方法是:用 LoadLibrary 函数加载动态链接库到内存,用 GetProcAddress函数动态获得 DLL 函数的入口地址。当一个 DLL 文件用 Lo...

weixin_30278311的博客 413

COM组件开发知识重点——COM原理与应用篇(二)

第3章 COM的实现 3.1 进程内组件(DLL)的实现,可以参考DLL技术,主要参数为: 1)LoadLibrary:装载DLL模块 2)GetProcAddress:取引出函数的地址 3)FreeLibrary:释放DLL模块     COM采用LPC(本地过程调用)和RPC(远程过程调用)的方法进行进程之间的通信,LPC用于在同一机器上的不同进程之间进行通信,而RPC用于在不同机器

guoduhua的专栏 4842

COM技术入门基础知识

这几天在学习COM组件技术,网上看了很多教程,发现有一些很基础的东西基本都没有涉及,下面我就结合网上的一些教程加上自己的体会来进行一些总结。   (1)COM组件是什么?    COM组件由以Win 32动态连接库(DLL)或可执行文件(EXE)形式发布的可执行代码所组成。再向深入了看,以C++为例,COM组件实际上就是一些实现了特定接口的类,而接口都是纯虚类。组件从接口派生而来。我们

军说网事 2003

Com对象的解释

⊙ 第一章 概述   COM 是什么   COM 对象与接口   COM 进程模型   COM 可重用性⊙ 第二章 COM 对象模型   全局唯一标识符 GUID   COM 对象   COM 接口   接口描述语言 IDL   IUnknown 接口   COM 对象的接口原则⊙ 第三章 COM 的实现   COM 组件注册信息   注册 COM 组件   类厂和 DllGetObject

EdisonGG的专栏 3995

COM(3)

3.1 进程内组件和进程外组件 3.1.1 进程内组件 3.1.2 进程外组件 3.2 通过注册表管理COM对象 3.2.1 注册表结构 3.2.2 COM组件注册信息 3.2.3 COM组件的注册操作 3.3 类厂 3.3.1 类厂和DllGetClassObject函数 3.3.2 COM库与类厂的交互 3.3.3 类厂的实现 3.3.4 类厂对组件生存期的控制 3.4

m00ndown 729

MFC程序运行时注册自身所需要的COM组件

我们可以在网上找到很多开发好的COM组件,这些组件提供了接口,我们可以对其进行二次开发,比如mp3play.ocx,通过这个控件,我们可以简单快速开发出自己的MP3播放器,COM组件可以是.ocx后缀,也可以是.dll后缀。熟悉VB开发的同志们对这些控件应该很熟悉吧。这些控件不仅可以用在VB中,同样可以用在VC等开发环境中。 在使用该控件时应该保证该电脑上已经注册了该控件。通常,我们都是通过安装

软件架构农 3901

【COM原理和应用】3、COM的实现

1、进程内组件和进程外组件 使用dll实现组件程序,则客户长须在调用组件程序的服务时,需要将dll装进自身的进程,所以客户程序和组件运行于同一进程空间,此类组件称为进程内组件。使用exe程序的组件,在被调用时自身具有进程空间,因此客户程序和组件运行在不同的进程空间,此类组件称之为进程外组件。 1.1、进程...

weixin_33893473的博客 157

《COM 原理与应用》学习笔记

《COM 原理与应用》学习笔记 - 第一部分 COM原理 按:文章对COM原理具有高度总结性,推荐学习COM的朋友都看一看,COM注定要淘汰的,但学习COM的编程思想是非常有意义的。   dREAMtHEATER推荐必属佳品   《COM 原理与应用》学习笔记 - 第一部分 COM原理   savetime2k@yahoo.com     (本文内容基本上是从《COM 原理与应用》书中摘录,版权由

linuszhu的专栏 2412
上一篇: 增量备份与差异备份的区别(Incremental vs. differential backup: A comparison)
下一篇: Writing a FilterUnloadCallback Routine for a Minifilter Driver
xbgprogrammer
博客等级 码龄20年 36粉丝 106原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值