ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 6887|回复: 5

留存,ProgID和ClsID之间转换,ClsID的字符串和数值形式的转换

[复制链接]

TA的精华主题

TA的得分主题

发表于 2013-3-26 19:59 | 显示全部楼层 |阅读模式
本帖已被收录到知识树中,索引项:Windows API应用



全局唯一标识符,简称GUID
通常表示成32个16进制数字(0-9,A-F)组成的字符串,如:{21EC2020-3AEA-1069-A2DD-08002B30309D},它实质上是一个128位长的二进制整数。在Windows系统中也称之为Class ID,缩写为CLSID。为了避免冲突,微软使用GUID作为CLSID,有生成GUID的函数,主要是根据当时的时间、机器地址等信息动态产生,理论上可保证全球唯一。
GUID本质上是一个16字节(128位)的二进制数,最常见[1]的结构如下:
位         字节         描述         字节序
32         4         数据1         原生
16         2         数据2         原生
16         2         数据3         原生
64         8         数据4         大端序


GUID通常会写成16进制数的字符串,如:3F2504E0-4F89-11D3-9A0C-0305E82C3301
这种文本表示包括了如下部分:
16进制数的位数         描述
8         数据1
4         数据2
4         数据3
4         数据4的最初2字节
12         数据4的剩余6字节

上述表示方法通常放在一对大括号里边,如:{3F2504E0-4F89-11D3-9A0C-0305E82C3301}


在开放软件基金会为计算(第一版)GUID制定的算法中,用户的网卡MAC地址被用于计算GUID中最后一组数字,所以就存在隐私问题,因为任何人都可以通过文件包含的GUID追溯到最初创建这个文件的电脑。这个漏洞曾被用于寻找梅丽莎病毒的制作者的位置[2]。在其它几组数字中,大多数是根据生成GUID的时间决定的。

我们可以通过GUID中第三组数字的第一位是不是1来判断它是否是第一版的GUID算法生成的,例如{2f1e4fc0-81fd-11da-9156-00036a0f876a}。

第四版的GUID使用了新的算法,其产生的数字是一个伪随机数。它生成的GUID的第三组数字的第一位是4,如{38a52be4-9352-453e-af97-5c3b448652f0}。对Windows API中的GUID生成器所做密码分析显示,因为第四版的GUID并不是真正随机的,所以只要知道了程序内部的全部状态,就可能预测它生成的上一个和下一个GUID的值。[3].


几个转换函数

函数         用途

StringFromCLSID      将CLSID转化成文本串

StringFromIID        将IID转化成文本串

StringFromGUID2      将GUID转化成文本串。此串将被存放在调用者所分配的缓冲区中

CLSIDFromString      将一个文本串转化成CLSID(128位数值)

IIDFromString        将一个文本串转化成IID



ProgID命名约定:
<Program>.<component>.<version>

从ProgID到CLSID的转换:COM库函数CLSIDFromProgID和ProgIdFromCLSID:

CLSID clsid;
    CLSIDFromProgID("****.****.****",&clsid);


DLL一定要输出下边两个函数:
STDAPI DllRegisterServer();
STDAPI DllUnregisterServer();

用户可以使用程序REGSVR32.EXE来注册某个组件,它实际上是通过上述函数来完成组件的注册的。

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-3-26 20:19 | 显示全部楼层
原帖:http://blog.csdn.net/Modest/archive/2006/11/01/1361160.aspx

[vb] view plaincopy
  1. Option Explicit  
  2.     Private Type UUID  
  3.         Data1 As Long  
  4.         Data2 As Integer  
  5.         Data3 As Integer  
  6.         Data4(7) As Byte  
  7.     End Type  
  8.     Private Declare Function CLSIDFromProgID Lib "ole32.dll" (ByVal lpszProgID As Long, pClsid As UUID) As Long  
  9.     Private Declare Sub ProgIDFromCLSID Lib "ole32.dll" (CLSID As UUID, lplpszProgID As Long)  
  10.     Private Declare Function CLSIDFromString Lib "ole32.dll" (ByVal lpszProgID As Long, pClsid As UUID) As Long  
  11.     Private Declare Function StringFromCLSID Lib "ole32.dll" (pClsid As UUID, lpszProgID As Long) As Long  
  12.     Private Declare Sub MoveMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)  
  13.     Public Function CLSIDToProgID(ByVal CLSID As String) As String  
  14.         Dim UUID As UUID  
  15.         Dim ProgID As Long  
  16.         Dim StrOut As String * 255  
  17.         CLSIDFromString StrPtr(CLSID), UUID  
  18.         ProgIDFromCLSID UUID, ProgID  
  19.         If ProgID <> 0 Then  
  20.             StrFromPtrW ProgID, StrOut  
  21.             CLSIDToProgID = Left(StrOut, InStr(StrOut, vbNullChar) - 1)  
  22.         End If  
  23.     End Function  
  24.     Public Function ProgIDToCLSID(ByVal ProgID As String) As String  
  25.         Dim UUID As UUID  
  26.         Dim CLSID As Long  
  27.         Dim StrOut As String * 255  
  28.         CLSIDFromProgID StrPtr(ProgID), UUID  
  29.         StringFromCLSID UUID, CLSID  
  30.         If CLSID <> 0 Then  
  31.             StrFromPtrW CLSID, StrOut  
  32.             ProgIDToCLSID = Left(StrOut, InStr(StrOut, vbNullChar) - 1)  
  33.         End If  
  34.     End Function  
  35.     Private Sub StrFromPtrW(pOLESTR As Long, StrOut As String)  
  36.         Dim ByteArray(255) As Byte, i As Integer  
  37.         Dim intTemp As Integer, intCount As Integer  
  38.          
  39.         intTemp = 1  
  40.         While intTemp <> 0  
  41.             MoveMemory intTemp, ByVal pOLESTR + i, 2  
  42.             ByteArray(intCount) = intTemp  
  43.             intCount = intCount + 1  
  44.             i = i + 2  
  45.         Wend  
  46.         MoveMemory ByVal StrOut, ByteArray(0), intCount  
  47.     End Sub
复制代码

TA的精华主题

TA的得分主题

发表于 2019-4-23 22:05 | 显示全部楼层
有了CLSID之后,就不需要获取ProgID了。可直接走IDispatch生成实例。

TA的精华主题

TA的得分主题

发表于 2019-5-6 00:09 | 显示全部楼层
忍不住把老魏的代码简化一下:
1.png

TA的精华主题

TA的得分主题

发表于 2019-8-19 12:05 | 显示全部楼层

SysReAllocString 崩溃

本帖最后由 lsqypj 于 2019-8-19 12:07 编辑
loquat 发表于 2019-5-6 00:09
忍不住把老魏的代码简化一下:


又试了下代码,程序每次到行到 SysReAllocString VarPtr(strProgID), lpszProgID 崩溃,Excel完全退出,调试看了下变量lpszProgID的值是一个负的整数,请教下是什么原因。。
操作系统是win10 64位,excel也是2016 64位

TA的精华主题

TA的得分主题

发表于 2019-8-22 10:47 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
木有64位系统,但是64位需要改代码。
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-11-24 05:15 , Processed in 0.036102 second(s), 11 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表