p简介
先得说下GUID,它是Globally Unique Identifier的简称,中文翻译为“全球唯一标示符”,在Windows系统中也称之为Class ID,缩写为CLSID。对于不同的应用程序,文件类型,OLE对象,特殊文件夹以及各种系统组件,Windows都会分配一个唯一表示它的ID代码 CLSID是一个128位的随机数,为了确保它的随机性,避免重复,它的算法主要是从两个方面入手:
1. 一部分数字来自于系统网卡的序列号,由于每一个网卡的MAC地址都不一样,因此产生的ID也就会有差异。
2. 另外一部分数字来自于系统的当前时间。
有人计算过按照上面两种方式得到ID的随机性,得出的结论是:即使一台电脑每秒产生10000000个CLSID,也可以保证3240年不会重复。
在注册表中展开HKEY_CLASSES_ROOT\CLSID\,在CLSID分支下面就可以看到很多的ID,这些ID对应的都是系统里面不同的程序,文件,系统组件等。
CLSID像人身份证一样,是个类的唯一标识。
id是唯一的标识,class则不是~class可以作为ID的样式或属性的补充!
class是对某种类型的对象定义变量和方法的原型。
ID身份 (identification, identity)
ID是英文IDentity的缩写,ID是身份标识号码的意思,就是一个序列号,也叫帐号,是一个编码,而且是唯一的。
为了避免冲突,微软使用GUID作为CLSID,有生成GUID的函数,主要是根据当时的时间、机器地址等信息动态产生,理论上可保证全球唯一。
常见组件类对应的CLSID:
我的文档:450D8FBA-AD25-11D0-98A8-0800361B1103
我的电脑:20D04FE0-3AEA-1069-A2D8-08002B30309D
网上邻居:208D2C60-3AEA-1069-A2D7-08002B30309D
回收站:645FF040-5081-101B-9F08-00AA002F954E
Internet Explorer:871C5380-42A0-1069-A2EA-08002B30309D
控制面板:21EC2020-3AEA-1069-A2DD-08002B30309D
拨号网络/网络连接:992CFFA0-F557-101A-88EC-00DD010CCC48
任务计划:D6277990-4C6A-11CF-8D87-00AA0060F5BF
打印机(和传真):2227A280-3AEA-1069-A2DE-08002B30309D
历史文件夹:7BD29E00-76C1-11CF-9DD0-00A0C9034933
公文包:85BBD920-42A0-1069-A2E4-08002B30309D
Web文件夹:BDEADF00-C265-11d0-BCED-00A0C90AB50F
网页:25336920-03F9-11CF-8FD0-00AA00686F13
恶意广告插件CLSID:
上面说到电脑上所有的的软件都有CLSID,那么恶意插件也有。比如下面的:
伪造IE浏览器:871C5380-42A0-1069-A2EA-08002B303099
如果你怀疑自己的电脑是否中了伪造IE浏览器恶意广告插件,进入注册表,发现有这段CLSID,那么就肯定中了。
名称 | 路径 | 含义
---------------------------------------------------------------------------
AppData C:\Windows\Application Data 应用程序
Cache C:\Windows\Temporary Internet Files 浏览器缓存
Cookies C:\Windows\Cookies
Desktop Desktop 桌面
Favorites Favorites 收藏夹
Fonts Fonts 字体
History History 历史文件夹
NetHood NetHood 网上邻居
Personal C:\My Documents 我的文档
PrintHood PrintHood 打印机
Program Start Menu\Programs 程序
Recent Recent 文档
SendTo SendTo 发送到
Start Menu Start Menu 开始菜单
Startup Start Menu\Programs\启动 启动组
Templates Temp 临时文件夹
******当需要修改这些系统文件夹的路径时,只需进入注册表的HKEY_CURRENT_USER\Software \Microsoft\Windows\CurrentVersion\Explorer\Shell Folders 中修改相应的路径即可。
********系统特殊的文件夹*********
在我们的桌面上或其他地方有一些文件夹并不是真正的文件夹,它们只是一个用来显示窗口文件夹内容的OLE对象,如“我的计算机”、“控制面板”等等,它们都有一个系统默认的类ID类标识,windows在注册表的HKEY_CLASSES_ROOT\CLSID下定义这些类。
文件夹 类ID 说明
-------------------------------------------------------------------------------------------------------
Control Panel {21EC2020-3AEA-1069-A2DD-08002B30309D} 控制面板
Dial-Up Networking {992CFFA0-F557-101A-88EC-00DD010CCC48} 拨号网络
Internet Explorer {BFB23B42-E3F0-101B-8488-00AA003E56F8} 浏览器
My Computer {20D04FE0-3AEA-1069-A2D8-08002B30309D} 我的电脑
Network Neighborhood {208D2C60-3AEA-1069-A2D7-08002B30309D} 网上邻居
Printers {2227A280-3AEA-1069-A2DE-08002B30309D} 打印机
Recycle Bin {645FF040-5081-101B-9F08-00AA002F984E} 回收站
Scheduled Tasks {D6277990-4C6A-11CF-8D87-00AA0060F5BF} 计划任务
My Documents {450D8FBA-AD25-11D0-98A8-0800361B1103} 我的文档
URLHistory Folder {FF393560-C2A7-11CF-BFF4-444553540000} URL历史
*************文件或其他对象的图标:*************
图标是一个文件或对象的标识。对于一个ICO文件只有一个唯一的图标, 可以用“路径\图标文件名”来指示该文件的图标;对于EXE、DLL等文件,它们可能要包含不止一个图标,这时就需要有一个索引标志来指明是第几个图标,可以用“路径\文件名,索引号”的形式来指示该文件的图标。
如果要修改系统文件夹的图标,只需进入注册表的HKEY_CLASSES_ROOT\CLSID中,查找到系统文件夹的类ID,然后修改 DefaultIcon中的图标文件路径即可;如果要修改其他文件的默认图标则需要在HKEY_CLASSES_ROOT\CLSID\"文件类型"\DefaultIcon中修改图标文件的路径。
***************驱动器的自动运行功能************
打开CDROM的自动运行功能并且放入可以自动运行的光盘时,光盘上的程序会自动运行,那么其他的诸入硬盘、移动盘等是否也可以自动运行哪?在注册表的HKEY_USERS\DEFAULT\Software\Microsoft\Windows\CurrentVersion\Policies\Exploer下可以看到有一个
NoDriveTypeAutoRun的值项,其中的值就指明了可以自动运行的驱动器。该值项是一个4字节的二进制值,第一字节的每位对应于不同的驱动器,如果对应位置为“1”则表示关闭自动运行功能,如果对应位置为“0”则表示打开自动运行功能。
下表是各位对应的驱动器类型:
第0位:未知驱动器
第2位:可移动驱动器
第3位:硬盘
第4位:远程驱动器
第5位:CDROM驱动器
第6位:RAM驱动器
作 用:删除系统无用的动态链接库(DLL文件)
路 径:HEKY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDLL
键值名称:
数据类型:
键 值:每个DLL文件的键值说明此DLL被几个应用程序共享
备 注:若为"01 00 00 00"则此DLL文件被一个应用程序共享。若为 "00 00 00 00"则该DLL文件
对系统不起作用,说明它是一个垃圾文件,删除该键值,并且记下这个 DLL文件名,从
\windows\system文件夹中将该DLL文件删除。
作 用:你的名字放入系统任务栏
路 径:HKEY_CURRENT_USER\Control Panel\International
键值名称:键值:sTimeFormat="HH:mm:-Ss tt",s1159="CFAN",s2359="HELLO"
数据类型:
键 值:说明:12点之前,在系统任务栏中显示CFAN,之后则显示HELLO,可任意设置以达到自己的效果
作 用:在每次退出系统时,自动清除文档菜单中的历史记录
路 径:HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer]
键值名称:"ClearRecentDocsonExit"
数据类型:十六进制
键 值:01,00,00,00
作 用:禁止"系统"中出现"设备管理器"选项
路 径:HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\System
键值名称:NoDevMgrPage
数据类型:DWORD
键 值:1
作 用:禁止"系统"中出现"文件系统"选项
路 径:HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\System
键值名称:NoFileSysPage
数据类型:DWORD
键 值:1
作 用:禁止"系统"中出现"硬件配置文件"选项
路 径:HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\System
键值名称:NoConfigPage
数据类型:DWORD
作 用:禁止在"系统属性"中出现"设备管理器"的菜单
路 径:HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\System
键值名称:新建 "NoDevMgrPage"
数据类型:DWORD
键 值:设其值为"1"
作 用:禁止在"系统属性"中出现"文件系统"的菜单
路 径:HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\System
键值名称:新建 "NoFileSysPage"
数据类型:DWORD
键 值:设其值为"1"
作 用:禁止在"系统属性"中出现"虚拟内存"的菜单
路 径:HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\System
键值名称:新建 "NoVirtMemPage"
数据类型:DWORD
键 值:设其值为"1"
当初微软设计com规范的时候,有两种选择来保证用户的设计的com组件可以全球唯一:
第一种是采用和Internet地址一样的管理方式,成立一个管理机构,用户如果想开发一个COM组件的时候需要向该机构提出申请,并交一定的费用。
第二种是发明一种算法,每次都能产生一个全球唯一的COM组件标识符。
第一种方法,用户使用起来太不方便, 微软采用第二种方法,并发明了一种算法,这种算法用GUID(Globally Unique Identifiers)来标识COM组件,GUID是一个128位长的数字,一般用16进制表示。
算法的核心思想是结合机器的网卡、当地时间、一个随即 数来生成GUID。从理论上讲,如果一台机器每秒产生10000000个GUID,则可以保证(概率意义上)3240年不重复。
GUID的例子:
54BF6567--1007--11D1--B0AA--444553540000
HKEY_CLASSES_ROOT\CLSID\{002B9E07-2E10-438F-AF1E-40E6A96F1EE4}
在微软的COM中GUID和UUID、CLSID、IID是一回事,只不过各自代表的意义不同:
UUID : 代表COM
CLSID : 代表COM组件中的类
IID :代表COM组件中的接口
在程序中,实际对象数据对应的处理程序路径string往往不尽相同,比如有的放C盘有的D盘,微软想出了一个解决方案,那就是不使用直接的路径表示方法,而使用一个叫 CLSID的方式间接描述这些对象数据的处理程序路径。
CLSID 其实就是一个号码,CLSID 的结构定义如下:
typedef struct _GUID {
DWORD Data1; // 随机数
WORD Data2; // 和时间相关
WORD Data3; // 和时间相关
BYTE Data4[8]; // 和网卡MAC相关
} GUID;
typedef GUID CLSID; // 组件ID
typedef GUID IID; // 接口ID
#define REFCLSID const CLSID &
// 常见的声明和赋值方法
CLSID CLSID_Excel = {0x00024500,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
struct __declspec(uuid("00024500-0000-0000-C000-000000000046")) CLSID_Excel;
class DECLSPEC_UUID("00024500-0000-0000-C000-000000000046") CLSID_Excel;
// 注册表中的表示方法
{00024500-0000-0000-C000-000000000046}
如果使用开发环境编写组件程序,则IDE会自动帮你产生 CLSID;
可以用函数 CoCreateGuid() 产生 CLSID;
使用"vc目录\Common\Tools\GuidGen.exe"工具产生GUID
每一个COM组件都需要指定一个 CLSID,并且不能重名。它之所以使用16个字节,就是要从概率上保证重复是“不可能”的。但是,微软为了使用方便,也支持另一个字符串名称方式,叫 ProgID。。由于 CLSID 和 ProgID 其实是一个概念的两个不同的表示形式,所以我们在程序中可以随便使用任何一种。
下面是 CLSID 和 ProgID 之间的转换方法和相关的函数:
函数 | 功能说明 |
CLSIDFromProgID()、CLSIDFromProgIDEx() | 由 ProgID 得到 CLSID。没什么好说的,你自己都可以写,查注册表贝 |
ProgIDFromCLSID() | 由 CLSID 得到 ProgID,调用者使用完成后要释放 ProgID 的内存(注5) |
CoCreateGuid() | 随机生成一个 GUID |
IsEqualGUID()、IsEqualCLSID()、IsEqualIID() | 比较2个ID是否相等 |
StringFromCLSID()、StringFromGUID2()、StringFromIID() | 由 CLSID,IID 得到注册表中CLSID样式的字符串,注意释放内存 |
客户端软件和组件之间的调用如下:
容器 协商部分 | 组件 应答部分 | |
1 | 根据CLSID启动组件 。 | 生成对象,执行构造函数,执行初始化动作。 |
2 | 你有IUnknown接口吗? | 有,给你! |
3 | 恩,太好了,那么你有IPersistStorage接口吗?(注9) | 没有! |
4 | 真差劲,连这个都没有。那你有IPersistStreamInit接口吗?(注10) | 哈,这个有,给! |
5 | 好,好,这还差不多。你现在给我初始化吧。 | OK,初始化完成了。 |
6 | 完成了?好!现在你读数据去吧。 | 读完啦。我根据数据,已经在窗口中显示出来了。 |
7 | 好,现在咱们各自处理用户的鼠标、键盘消息吧...... | ...... |
8 | 哎呀!用户要保存退出程序了。你的数据被用户修改了吗? | 改了,用户已经修改啦。 |
9 | 那好,那么用户修改后,你的数据需要多大的存储空间呀? | 恩,我算算呀......好了,总共需要500KB。 |
10 | 晕,你这么个小玩意居然占用这么大空间?!......好了,你可以存了。 | 谢谢,我已经存好了。 |
11 | 恩。拜拜了您那。(注11) | 执行析构函数,删除对象。 |
12 | 我自己也该退出了...... |
|