国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > VBScript > 正文

VBS技術內幕:CreateObject函數詳解

2020-07-26 11:44:55
字體:
來源:轉載
供稿:網友

曾經我也不明白為什么在CreateObject函數中傳遞不同的字符串就可以創建各種各樣功能強大的對象。后來無意中看到UMU的《[UMU WSH 教程](9)CreateObject 過程》,才知道CreateObject函數創建的是COM對象,第一個參數是COM對象的ProgID。再后來拜讀了Jeff Glatt的《COM in plain C》,知道了如何用純C語言編寫COM組件。

COM(組件對象模型)是一個很復雜的概念,需要用磚頭那么厚的書才能講得清楚,而且沒有C++和面向對象編程背景的話很難理解,比較經典的書有《COM原理與應用》、《COM技術內幕》和《COM本質論》,不過貌似都絕版了。

當然,作為VBSer,我們不需要去理解COM的原理或者本質。簡單的說,COM就是別人寫好的模塊,我們要做的僅僅是調用它,而不必關心它的內部實現,這也是COM技術的一個初衷。ProgID可以認為是開發人員為COM對象起的一個名字,我們把COM對象的名字傳遞給CreateObject函數,告訴它我們想創建這個對象,CreateObject函數就會返回這個對象的指針給你。

例如我可以(當然,你也可以)用VB來編寫一個COM組件,然后給它起個名字demon.tw,那么注冊該COM組件之后,就可以用CreateObject函數來創建了:

Set blog = CreateObject("demon.tw")blog.Open '假設我的COM對象實現了Open方法

我們常用的Scripting.FileSystemObject、WScript.Shell、ADODB.Stream等只不過是微軟開發的系統自帶的COM對象的名字罷了。

那么CreateObject函數是如何創建對象的呢?用OllyDbg跟了一下,核心的代碼大概可以分成四步:

第一步調用CLSIDFromProgIDEx從ProgID獲取對應的CLSID,如果找不到對應的CLSID,就會報錯“ActiveX 部件不能創建對象”。

我們可以用注冊表編輯器手工查找CLSID。例如要獲取WScript.Shell的CLSID,用注冊表編輯器查找HKEY_CLASSES_ROOT/WScript.Shell/CLSID的值即可。需要注意的是,《[UMU WSH 教程](9)CreateObject 過程》里說:

1、CreateObject 函數先檢查注冊表 HKEY_CLASSES_ROOT/WScript.Shell 下的子鍵 CurVer 的默認值,結果為 WScript.Shell.1,所以知道最新版本是 WScript.Shell.1;

2、讀 HKEY_CLASSES_ROOT/WScript.Shell.1,下面有一個子鍵 CLSID,默認值為 {72C24DD5-D70A-438B-8A42-98424B88AFB8};

這是錯誤的,CreateObject函數(準確的說是其內部調用的CLSIDFromProgIDEx函數)先檢查注冊表子鍵 HKEY_CLASSES_ROOT/WScript.Shell/CLSID是否存在,只要子鍵存在,即使默認值為空或者不是類標識符,都不會再檢查子鍵CurVer ,只有CLSID子鍵不存在,才會檢查子鍵 CurVer。

第二步調用CoGetClassObject函數獲取IClassFactory接口的指針,如果獲取不到,報錯“ActiveX 部件不能創建對象”或者“類不支持 Automation 操作”,也可能是其他錯誤信息,這取決于COM的實現。

第三步調用IClassFactory接口的CreateInstance方法獲取IUnknown接口指針,所有的COM都必須支持IUnknown接口,所以這步應該不會出錯。

最后調用IUnknown接口的QueryInterface方法查詢該COM是非支持IDispatch接口,只有支持IDispatch接口的COM類才能用CreateObject創建對象。如果獲取到IDispatch接口的指針,就可以給VARIANT變量賦值了;如果不支持IDispatch接口,報錯“類不支持 Automation 操作”,也可能是其他錯誤信息,取決于具體實現。

說了半天還是沒有說到一個關鍵的問題:VBS到底能調用哪些對象?或者說,哪些字符串可以作為CreateObject函數的第一個參數?欲知問題答案,請聽下回分解。

VBS深入CreateObject函數

本篇要講的是對象的創建,屬于 COM 的內容,這里不可能說太多,大家可以找一些 COM 的書看看,也可以看看 UMU 的其他關于 COM 的文章:《ATL 體驗》、《基于 WebBrowser 的新型應用程序研究小記》、《學習 ATL 的理由》、《關于 COM 的幾個概念問題》、《關于 COM 的幾個概念問題(2)》。最常見的對象有:WScript.Shell、Scripting.FileSystemObject、Scripting.Dictionary 等,這里以 WScript.Shell 為例。


馬上來看對象的創建過程,語句 Set objWSH = CreateObject( "WScript.Shell" ):

1、CreateObject 函數先檢查注冊表 HKEY_CLASSES_ROOT/WScript.Shell 下的子鍵 CurVer 的默認值,結果為 WScript.Shell.1,所以知道最新版本是 WScript.Shell.1;

2、讀 HKEY_CLASSES_ROOT/WScript.Shell.1,下面有一個子鍵 CLSID,默認值為 {72C24DD5-D70A-438B-8A42-98424B88AFB8};

3、找到了 HKEY_CLASSES_ROOT/CLSID/{72C24DD5-D70A-438B-8A42-98424B88AFB8},子鍵 InProcServer32 的默認值說明服務程序是 C:/WINDOWS/system32/wshom.ocx。

4、對于腳本可以調用的 COM 對象,要使用對象里的方法 TypeLib 是必要的,HKEY_CLASSES_ROOT/CLSID/{72C24DD5-D70A-438B-8A42-98424B88AFB8} /TypeLib 的默認值是 {F935DC20-1CF0-11D0-ADB9-00C04FD58A0B},HKEY_CLASSES_ROOT/TypeLib /{F935DC20-1CF0-11D0-ADB9-00C04FD58A0B}/1.0/0/win32 的默認值說明類型庫是 C:/WINDOWS/system32/wshom.ocx。

支持腳本調用的 COM 對象必然要實現 IDispatch 接口,可以從 C:/WINDOWS/system32/wshom.ocx 的“資源

主站蜘蛛池模板: 铜鼓县| 余姚市| 女性| 儋州市| 德钦县| 忻城县| 安岳县| 眉山市| 祁连县| 革吉县| 清苑县| 永登县| 铅山县| 淮阳县| 山东| 越西县| 青铜峡市| 新密市| 和田县| 嵊州市| 化州市| 南部县| 永登县| 宣汉县| 秭归县| 苍梧县| 通江县| 桐乡市| 武强县| 景泰县| 高陵县| 新蔡县| 裕民县| 姜堰市| 高台县| 秦皇岛市| 同江市| 徐州市| 屏南县| 耒阳市| 呈贡县|