Windows Scripting Technology
堅果 Jimbowhy 前后端腳本編程輕松篇集合文章:
- 輕松搭建PHP開發(fā)環(huán)境Win32
- 小而巧 editplus 腳本編程
- Windows Script Technology
- 看我怎樣把editplus用巧
- HTTP協(xié)議入門與Fiddler抓包
Windows Script Host & Windows Script File
接上一文小而巧 editplus 腳本編程繼續(xù), Windows 腳本文件 .wsf 和 .wsh 是含有可擴展標記語言 (XML) 代碼的文本文檔, (.wsh)主要用來設(shè)置和自定義腳本屬性. 通過 Include 語句復(fù)用 js 和 vbs 腳本文件, 可同時使用多種腳本文件類型, 這樣編寫腳本時就可以按文件來進行功能分類了. 支持類型庫, 在下面的示例中的ActiveX控件 "MyComponent" 可以用 Microsoft Visual Basic 5.0 開發(fā), 即 Visual Studio 97 包含的 Visual Basic. 通過 reference 來引用 progID 指定的類庫后, 腳本就可以使用庫定義好的常數(shù)了, 類庫信息可以在這些文件中找到 .tlb, .olb, .dll .
<job id="IncludeExample">
<reference progid="MyComponent.MyClass">
<script language="JScript" src="some.js"/>
<script language="VBScript">
Set MyVar = CreateObject("MyComponent.MyClass")
'call function from script file ...
<script>
</job>
WSF中有兩個重要的元素 <object> 和 <reference>, 在理解這兩個元素之前, 可以簡單理解為前者是實例化一個類, 后者是應(yīng)用一個類型庫以使用庫里面的一些常量定義等. 要深入理解, 就要先弄清 progID 和 CLSID. 先來說說ID, 及 Identifier 唯一標識. 重復(fù)是一個普遍的現(xiàn)象, 書的名字會有重復(fù)的, 人的也會有重名的 progID, 自然的重復(fù)就就常態(tài). 但是計算機的編碼也是0和1的重復(fù), 但是這種重復(fù)現(xiàn)象在編程過程就必須避免, 否則就會導(dǎo)致邏輯胡亂, 程序更無法正常運行. 據(jù)說當初微軟設(shè)計com規(guī)范的時候. 有兩種選擇來保證用戶的設(shè)計的com組件可以全球唯一. 第一種是采用和Internet地址一樣的管理方式, 成立一個管理機構(gòu)舷手,用戶如果想開發(fā)一個COM組件的時候需要向該機構(gòu)提出申請, 并交一定的費用. 我第一次看到這種說法時覺得好笑,可是在當時那個時代劲绪,這種事確實可能會發(fā)生. 但最后實施時是用一種算法男窟,每次都能產(chǎn)生一個全球唯一的COM組件標識符. 這種算法用 Globally Unique Identifiers 即GUID來標識COM組件, GUID是一個128位長的數(shù)字, 一般用16進制分成五段表示, 開頭這段是隨機數(shù), 接著是兩段時間戳, 最后兩段是網(wǎng)卡MAC相關(guān)數(shù), 就是文中看到的這些 CLSID. 算法的核心思想是結(jié)合機器的網(wǎng)卡, 當?shù)貢r間, 一個隨即數(shù)來生成GUID. 從理論上講, 如果一臺機器每秒產(chǎn)生10000000個GUID, 則可以在高概率保證3240年不重復(fù). 所以 GUID 是在目前這個計算機速度前提下成立的, 如果以后的機器速度夠快, 那同樣的時間內(nèi)生成的 GUID 就會更多, 重復(fù)的概率也就越大, 到一定條件下可能就失去作用了. 從唯一標識這個角度看, 微軟COM技術(shù)中的 GUID, UUID, CLSID, IID 是一回事盆赤,只不過各自代表的意義不同:
UUID 代表COM
CLSID 代表COM組件中的類
IID 代表COM組件中的接口
來看看他們在C語言下的結(jié)構(gòu)定義就更清晰了:
typedef struct _GUID {
DWORD Data1; // 隨機數(shù)
WORD Data2; // 和時間相關(guān)
WORD Data3; // 和時間相關(guān)
BYTE Data4[8]; // 和網(wǎng)卡MAC相關(guān)
} GUID;
typedef GUID CLSID; // 組件ID
typedef GUID IID; // 接口ID
#define REFCLSID const CLSID &
每一個COM組件都需要指定一個 CLSID 保證重復(fù)是“不可能”的, 但是這樣的一組數(shù)碼不方便開發(fā)者使用,因此, 另一種字符串名稱方式也就是 ProgID 被用上了, 通過注冊表 HKEY_CLASSES_ROOT 來查找系統(tǒng)已經(jīng)注冊的 ProgID 組件類型, 都按 Library.Class 這種方式命名, 這個名字就可用 WSF 的 <object> 元素的 ProgID 中, 如 Word.Application, 在執(zhí)行 new ActiveXObject 就是從這里獲取信息的. 以下導(dǎo)出的注冊表信息供參考:
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\Scripting.Dictionary]
@="Scripting.Dictionary"
[HKEY_CLASSES_ROOT\Scripting.Dictionary\CLSID]
@="{EE09B103-97E0-11CF-978F-00A02463E06F}"
[HKEY_CLASSES_ROOT\Scripting.FileSystemObject]
@="FileSystem Object"
[HKEY_CLASSES_ROOT\Scripting.FileSystemObject\CLSID]
@="{0D43FE01-F093-11CF-8940-00A0C9054228}"
[HKEY_CLASSES_ROOT\Word.Application]
@="Microsoft Word Application"
[HKEY_CLASSES_ROOT\Word.Application\CLSID]
@="{000209FF-0000-0000-C000-000000000046}"
[HKEY_CLASSES_ROOT\Word.Application\CurVer]
@="Word.Application.12"
[HKEY_CLASSES_ROOT\Word.Document]
@="Microsoft Office Word Document"
[HKEY_CLASSES_ROOT\Word.Document\CLSID]
@="{F4754C9B-64F5-4B40-8AF4-679732AC0607}"
[HKEY_CLASSES_ROOT\Word.Document\CurVer]
@="Word.Document.12"
再細看每個類型中包含一個 CLSID 子鍵, 里面的值就是加載組件的依據(jù), 系統(tǒng)會通過這個值來查詢注冊表的 HKEY_CLASSES_ROOT\CLSID, 這里包含了類型庫的詳細信息, 如程序文件的位置, 來看看這里的注冊表內(nèi)容:
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\CLSID\{88D969EA-F192-11D4-A65F-0040963251E5}]
@="XML HTTP 5.0"
[HKEY_CLASSES_ROOT\CLSID\{88D969EA-F192-11D4-A65F-0040963251E5}\InProcServer32]
@="C:\\Program Files\\Common Files\\Microsoft Shared\\OFFICE11\\msxml5.dll"
"ThreadingModel"="Apartment"
[HKEY_CLASSES_ROOT\CLSID\{88D969EA-F192-11D4-A65F-0040963251E5}\ProgID]
@="Msxml2.XMLHTTP.5.0"
[HKEY_CLASSES_ROOT\CLSID\{88D969EA-F192-11D4-A65F-0040963251E5}\TypeLib]
@="{F5078F18-C551-11D3-89B9-0000F81FE221}"
[HKEY_CLASSES_ROOT\CLSID\{88D969EA-F192-11D4-A65F-0040963251E5}\Version]
@="5.0"
[HKEY_CLASSES_ROOT\CLSID\{88d96a0a-f192-11d4-a65f-0040963251e5}]
@="XML HTTP 6.0"
[HKEY_CLASSES_ROOT\CLSID\{88d96a0a-f192-11d4-a65f-0040963251e5}\InProcServer32]
@="%SystemRoot%\System32\msxml6.dll"
"ThreadingModel"="Apartment"
[HKEY_CLASSES_ROOT\CLSID\{88d96a0a-f192-11d4-a65f-0040963251e5}\ProgID]
@="Msxml2.XMLHTTP.6.0"
[HKEY_CLASSES_ROOT\CLSID\{88d96a0a-f192-11d4-a65f-0040963251e5}\TypeLib]
@="{F5078F18-C551-11D3-89B9-0000F81FE221}"
[HKEY_CLASSES_ROOT\CLSID\{88d96a0a-f192-11d4-a65f-0040963251e5}\Version]
@="6.0"
這里留意 TypeLib, 上面羅列的 Msxml2.XMLHTTP.5.0 和 Msxml2.XMLHTTP.6.0 都歸屬同一個庫, 跟著這個庫的 GUID 又可以在 注冊表的這個位置 HKEY_CLASSES_ROOT\TypeLib 找到類型庫信息
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\TypeLib\{F5078F18-C551-11D3-89B9-0000F81FE221}]
[HKEY_CLASSES_ROOT\TypeLib\{F5078F18-C551-11D3-89B9-0000F81FE221}\3.0]
@="Microsoft XML, v3.0"
[HKEY_CLASSES_ROOT\TypeLib\{F5078F18-C551-11D3-89B9-0000F81FE221}\3.0\0\win32]
@="%SystemRoot%\System32\msxml3.dll"
[HKEY_CLASSES_ROOT\TypeLib\{F5078F18-C551-11D3-89B9-0000F81FE221}\3.0\FLAGS]
@="0"
[HKEY_CLASSES_ROOT\TypeLib\{F5078F18-C551-11D3-89B9-0000F81FE221}\4.0]
@="Microsoft XML, v4.0"
[HKEY_CLASSES_ROOT\TypeLib\{F5078F18-C551-11D3-89B9-0000F81FE221}\4.0\0\win32]
@="C:\\windows\\SysWow64\\msxml4.dll"
[HKEY_CLASSES_ROOT\TypeLib\{F5078F18-C551-11D3-89B9-0000F81FE221}\4.0\FLAGS]
@="0"
[HKEY_CLASSES_ROOT\TypeLib\{F5078F18-C551-11D3-89B9-0000F81FE221}\4.0\HELPDIR]
@="C:\\windows\\system32"
[HKEY_CLASSES_ROOT\TypeLib\{F5078F18-C551-11D3-89B9-0000F81FE221}\5.0]
@="Microsoft XML, v5.0"
[HKEY_CLASSES_ROOT\TypeLib\{F5078F18-C551-11D3-89B9-0000F81FE221}\5.0\0\win32]
@="C:\\Program Files\\Common Files\\Microsoft Shared\\OFFICE11\\msxml5.dll"
[HKEY_CLASSES_ROOT\TypeLib\{F5078F18-C551-11D3-89B9-0000F81FE221}\5.0\FLAGS]
@="0"
[HKEY_CLASSES_ROOT\TypeLib\{F5078F18-C551-11D3-89B9-0000F81FE221}\5.0\HELPDIR]
@="C:\\Program Files\\Common Files\\Microsoft Shared\\OFFICE11\\"
[HKEY_CLASSES_ROOT\TypeLib\{F5078F18-C551-11D3-89B9-0000F81FE221}\6.0]
@="Microsoft XML, v6.0"
[HKEY_CLASSES_ROOT\TypeLib\{F5078F18-C551-11D3-89B9-0000F81FE221}\6.0\0\win32]
@=%SystemRoot%\System32\msxml6.dll
[HKEY_CLASSES_ROOT\TypeLib\{F5078F18-C551-11D3-89B9-0000F81FE221}\6.0\FLAGS]
@="0"
在WSF中使用 <reference> 元素是就是使用這個 TypeLib 的 GUID. 所以, 可以在WSF中這樣定義:
<reference id="Microsoft Visual Basic 5.0 Extensibility" guid="{EF404E00-EDA6-101A-8DAF-00DD010F7EBB}" version="5.0"/>
<reference id="Microsoft WinHTTP Services, version 5.1" guid="{662901FC-6951-4854-9EB2-D9A2570F2B2E}" version="5.0"/>
<reference id="Microsoft Script Control 1.0" guid="{0E59F1D2-1FBE-11D0-8FF2-00A0D10038BC}" version="1.0"/>
<object id="word" progid="Word.Application" events="true"/>
<object id="fso" progid="Scripting.FileSystemObject" events="true" reference="true"/>
<object id="ie" progid="InternetExplorer.Application" events="true" reference="false"/>
<object id="encoder" progid="Scripting.Encoder" events="true" reference="false"/>
<obect id="fso" progid="Scripting.FileSystemObject"/>
但是不能這樣定義, 因為 Word.Application 是類對象而不是類型庫:
<reference object="Word.Application" />
請注意, VBScript 強制引用 Visual Basic For Applications, 可以通過以下語句測試任一個常數(shù)如 vbAbort, 在 VBScript 腳本中是可以讀取的, 但是在 JScript 就不能, 很不統(tǒng)一的邏輯問題, 應(yīng)該算是八阿哥. 并且也不能在腳本塊中進行引用, 因為 VBScript 默認就是引用的, 所以, 添加以下VBA引用后, 腳本就不能正常工作了, 錯誤提示也不是找不到類庫, 而是不能加載類庫. 因為, 有引用的類庫和默認的有沖突, 這一點很像 Visual Basic 5.0 工程中不能移除 VBA 引用, 也不能添加其它版本 VBA 庫一樣蝎宇。
MsgBox "VB Const vbAbort=" & vbAbort
<reference id="Visual Basic For Applications 5.0" guid="{000204EF-0000-0000-C000-000000000046}" version="5.0"/>
<reference id="Visual Basic For Applications 6.0" guid="{EA544A21-C82D-11D1-A3E4-00A0C90AEA82}" version="6.0"/>
為了方便 JScript 使用VB常數(shù), 我將常用的 MsgBox 常數(shù)整理到 vbconst.js, 只要引入它就可以使用了. 處理這些常數(shù)我是使用正則表達來處理的, 在 editplus 的替換功能中, 只需要以下兩條正則式子即可:
Find What: ^(\w+)\t(\d*)
Replace: var \1 = \2; //
然后就可以得到整理好的 JScript 代碼, 分毫不差快速有效率:
// vbconst.js
function test(){
return WScript.Name
}
// MsgBox Arguments
// Constant Value Description
var vbOKOnly = 0; // OK button only (default)
var vbOKCancel = 1; // OK and Cancel buttons
var vbAbortRetryIgnore = 2; // Abort, Retry, and Ignore buttons
var vbYesNoCancel = 3; // Yes, No, and Cancel buttons
var vbYesNo = 4; // Yes and No buttons
var vbRetryCancel = 5; // Retry and Cancel buttons
var vbCritical = 16; // Critical message
var vbQuestion = 32; // Warning query
var vbExclamation = 48; // Warning message
var vbInformation = 64; // Information message
var vbDefaultButton1 = 0; // First button is default (default)
var vbDefaultButton2 = 256; // Second button is default
var vbDefaultButton3 = 512; // Third button is default
var vbDefaultButton4 = 768; // Fourth button is default
var vbApplicationModal = 0; // Application modal message box (default)
var vbSystemModal = 4096; // System modal message box
var vbMsgBoxHelpButton = 16384; // Adds Help button to the message box
var VbMsgBoxSetForeground = 65536; // Specifies the message box window as the foreground window
var vbMsgBoxRight = 524288; // Text is right aligned
var vbMsgBoxRtlReading = 1048576; // Specifies text should appear as right-to-left reading on Hebrew and Arabic systems
// MsgBox Return Values
// Constant Value Description
var vbOK = 1; // OK button pressed
var vbCancel = 2; // Cancel button pressed
var vbAbort = 3; // Abort button pressed
var vbRetry = 4; // Retry button pressed
var vbIgnore = 5; // Ignore button pressed
var vbYes = 6; // Yes button pressed
var vbNo = 7; // No button pressed
到這里, 應(yīng)該掌握像 PrimalScript 這樣的程序是如何生成對象和引用列表的了. 也應(yīng)該理解開發(fā)COM組件時會用到的類似 CLSIDFromProgID(), CLSIDFromProgIDEx() 這樣的方法是如何由 ProgID 得到 CLSID, 就是通過注冊表API查詢唄.
PAUSE! 寫到這里, 我不得不給 Sublime 打 CALL啦, 一個 Unregistered 的軟件, 用起來竟然可以這么流暢, Ctrl+R 快速定位代碼可行定位可以方法定位, 更別說那提示同樣敏捷. 它的 Package Control 提供強大的擴展性, 可以加裝 SFTP, 可以加裝 github 等等弟劲, 太多太贊了。按下 Ctrl+Shift+P, 輸入 Package Control, 回車安裝它. 完后再來一次, 輸入 Install Package, 回車安裝它. 現(xiàn)在的 Sublime 以可以開始暴力圈粉模式了, 同樣按下 Ctrl+Shift+P, 輸入 Install Package, 對就是上一步的重復(fù), 只不過這次不是安裝 Install Package, 而是其他工具的 Package, 這次要等 Install Package 更新可用工具包列表, 住意狀態(tài)欄, 完了就可以輸入想要的工具了, sftp 自然不在話下, Markdown Preview 也是可以有的. 不同的工具出行的菜單位置不同, SFTP 是在文件菜單, Markdown Preview 則在 tools=>build system, 打開MD文件, 選擇 build system 里的 Markdown, 然后按下 Ctrl+B 編譯 md 文件, 就會生成一個 html 頁面. 也可以換個方式, 依次按下 Ctrl+Shift+P => Markdown, 看看是不是出現(xiàn) Preview in Browser, 對沒錯選他, 立刻就在瀏覽器看到渲染后的 md 文檔.
回到正題, 從OOP的觀點來看, 注冊表的相關(guān)信息是對應(yīng)的, 包括注冊表的一個 Interface 子鍵, 完整思維導(dǎo)圖是這個樣的:
[HKEY_CLASSES_ROOT\Interface\{IID}\]
[HKEY_CLASSES_ROOT\TypeLib]
[HKEY_CLASSES_ROOT\CLSID]
[HKEY_CLASSES_ROOT\(ProgID)]
注冊表的(ProgID)子鍵下設(shè)關(guān)聯(lián)CLSID, 這是一對一關(guān)聯(lián), CLSID子鍵下會有多個子鍵與TypeLib關(guān)聯(lián), 因為庫是包含多個類的, 這就一致的. Interface 對應(yīng)接口, ID也按IID這樣表示, 類實現(xiàn)接口與否沒有強制.
為了查詢方便, 我將editplus配置為命令行輔助工具, 按以下要求給 editplus 添加一個用戶工具, 這樣就可以在 editplus 中輸入命令行而不必到系統(tǒng)中打開 cmd.exe 來執(zhí)行命令了:
Text=Execute Line
Command=$(CurLineText)
ACTiON=Capture output
Save=None
配置完后, 只需要在 editplus 輸入類似以下的命令, 然后光標停在準備執(zhí)行的行, 按下快捷鍵, editplus 就會捕捉命令輸出的內(nèi)容, 這樣可以避免多開程序窗口, 也免去了程序切換的麻煩:
cmd.exe /c dir c:\
reg.exe query /?
接下來, 通過以下注冊表命令來查詢需要的信息:
reg.exe query HKCR\Microsoft.XMLHTTP /s
reg.exe query HKCR\MSXML2.XMLHTTP /ve
reg.exe query HKCR\MSXML2.XMLHTTP /s
reg.exe query HKCR\Msxml2.ServerXMLHTTP.6.0 /s
reg.exe query HKCR\Word.Application /s
reg.exe query HKCR\CLSID\{88d96a0b-f192-11d4-a65f-0040963251e5} /s
reg.exe query HKCR\TypeLib\{0E59F1D2-1FBE-11D0-8FF2-00A0D10038BC} /s
還有一個自動定位注冊表位置的小技巧, 注冊表關(guān)閉時會將最后的位置存儲到 LastKey 中, 下次打開時就還原到這個位置, 因此, 利用這個巧點可以實現(xiàn)注冊表的自動定位:
cmd /c reg.exe add HKCU\Software\Microsoft\Windows\CurrentVersion\Applets\Regedit /f /v LastKey /t REG_SZ /d HKEY_CLASSES_ROOT\Word.Application && regedit.exe
cmd /c reg.exe add HKCU\Software\Microsoft\Windows\CurrentVersion\Applets\Regedit /f /v LastKey /t REG_SZ /d HKEY_CLASSES_ROOT\scriptletfile && regedit.exe
注冊表維護
腳本能否運行和注冊表有很大的關(guān)系, Windows 會在注冊表將腳本解析引擎與特定的腳本文件類型關(guān)聯(lián)起來, 如果軟件操作不當, 損壞了相關(guān)信息, 則可能導(dǎo)致腳本不能正常運行, 以下命令就可以用來查看腳本文件的關(guān)聯(lián)信息:
reg.exe query HKCR\.vbs /s
reg.exe query HKCR\.js /s
reg.exe query HKCR\.wsf /s
reg.exe query HKCR\.wsc /s
本機就是安裝 ASE Admin Script Editor 出現(xiàn) js 腳本文件關(guān)聯(lián)問題, 導(dǎo)致腳本不能運行, 注冊表顯示 js 文件關(guān)聯(lián)類型是 EditPlus.js, 正確的應(yīng)該是 JSFile, :
reg.exe query HKCR\EditPlus.js /s
reg.exe query HKCR\vbsfile /s
HKEY_CLASSES_ROOT\.js
(默認) REG_SZ EditPlus.js
Content Type REG_SZ application/x-javascript
PerceivedType REG_SZ Text
修復(fù)命令行參考如下, 將正確文件類型關(guān)聯(lián)上即可:
reg.exe add HKEY_CLASSES_ROOT\.js /ve /t REG_SZ /f /d JSFile
reg.exe add HKEY_CLASSES_ROOT\.vbs /ve /t REG_SZ /f /d VBSFile
reg.exe add HKEY_CLASSES_ROOT\.vbs /ve /t REG_SZ /f /d WSFFile
reg.exe add HKEY_CLASSES_ROOT\.vbs /ve /t REG_SZ /f /d scriptletfile
這里是正確的注冊表信息, 損壞的系統(tǒng)可以參考進行修復(fù):
HKEY_CLASSES_ROOT\.js
(默認) REG_SZ JSFile
HKEY_CLASSES_ROOT\.js\PersistentHandler
(默認) REG_SZ {5e941d80-bf96-11cd-b579-08002b30bfeb}
HKEY_CLASSES_ROOT\.wsc
(默認) REG_SZ scriptletfile
Content Type REG_SZ text/scriptlet
HKEY_CLASSES_ROOT\.wsf
(默認) REG_SZ WSFFile
HKEY_CLASSES_ROOT\.vbs
(默認) REG_SZ VBSFile
HKEY_CLASSES_ROOT\.vbs\PersistentHandler
(默認) REG_SZ {5e941d80-bf96-11cd-b579-08002b30bfeb}
HKEY_CLASSES_ROOT\JSFile
FriendlyTypeName REG_EXPAND_SZ @%SystemRoot%\System32\wshext.dll,-4804
(默認) REG_SZ JavaScript File
HKEY_CLASSES_ROOT\JSFile\DefaultIcon
(默認) REG_SZ C:\Windows\System32\WScript.exe,3
HKEY_CLASSES_ROOT\JSFile\ScriptEngine
(默認) REG_SZ JScript
HKEY_CLASSES_ROOT\JSFile\ScriptHostEncode
(默認) REG_SZ {85131630-480C-11D2-B1F9-00C04F86C324}
HKEY_CLASSES_ROOT\JSFile\Shell
(默認) REG_SZ Open
HKEY_CLASSES_ROOT\JSFile\Shell\Edit\Command
(默認) REG_SZ C:\Windows\System32\Notepad.exe %1
HKEY_CLASSES_ROOT\JSFile\Shell\Open\Command
(默認) REG_SZ C:\Windows\System32\WScript.exe "%1" %*
HKEY_CLASSES_ROOT\JSFile\Shell\Open2
(默認) REG_SZ Open &with Command Prompt
MUIVerb REG_SZ @C:\Windows\System32\wshext.dll,-4511
HKEY_CLASSES_ROOT\JSFile\Shell\Open2\Command
(默認) REG_SZ C:\Windows\System32\CScript.exe "%1" %*
HKEY_CLASSES_ROOT\JSFile\Shell\Print\Command
(默認) REG_SZ C:\Windows\System32\Notepad.exe /p %1
HKEY_CLASSES_ROOT\JSFile\ShellEx\ContextMenuHandlers\OpenGLShExt
(默認) REG_SZ {E97DEC16-A50D-49bb-AE24-CF682282E08D}
HKEY_CLASSES_ROOT\JSFile\ShellEx\DropHandler
(默認) REG_SZ {60254CA5-953B-11CF-8C96-00AA00B8708C}
HKEY_CLASSES_ROOT\JSFile\ShellEx\PropertySheetHandlers\WSHProps
(默認) REG_SZ {60254CA5-953B-11CF-8C96-00AA00B8708C}
HKEY_CLASSES_ROOT\scriptletfile
(默認) REG_SZ Windows Script Component
HKEY_CLASSES_ROOT\scriptletfile\AutoRegister
(默認) REG_SZ C:\Windows\system32\scrobj.dll
HKEY_CLASSES_ROOT\scriptletfile\CLSID
(默認) REG_SZ {06290BD2-48AA-11D2-8432-006008C3FBFC}
HKEY_CLASSES_ROOT\scriptletfile\DefaultIcon
(默認) REG_SZ C:\Windows\system32\scrobj.dll,0
HKEY_CLASSES_ROOT\scriptletfile\ScriptHostEncode
(默認) REG_SZ {06290BD4-48AA-11D2-8432-006008C3FBFC}
HKEY_CLASSES_ROOT\scriptletfile\Shell\Generate Typelib
(默認) REG_SZ &Generate Type Library
HKEY_CLASSES_ROOT\scriptletfile\Shell\Generate Typelib\command
(默認) REG_SZ "C:\Windows\system32\RUNDLL32.EXE" "C:\Windows\system32\scrobj.dll",GenerateTypeLib "%1"
HKEY_CLASSES_ROOT\scriptletfile\Shell\Open
(默認) REG_SZ &Open
HKEY_CLASSES_ROOT\scriptletfile\Shell\Open\command
(默認) REG_SZ "C:\Windows\system32\NOTEPAD.EXE" "%1"
HKEY_CLASSES_ROOT\scriptletfile\Shell\Register
(默認) REG_SZ &Register
HKEY_CLASSES_ROOT\scriptletfile\Shell\Register\command
(默認) REG_SZ "C:\Windows\system32\REGSVR32.EXE" /i:"%1" "C:\Windows\system32\scrobj.dll"
HKEY_CLASSES_ROOT\scriptletfile\Shell\Unregister
(默認) REG_SZ &Unregister
HKEY_CLASSES_ROOT\scriptletfile\Shell\Unregister\command
(默認) REG_SZ "C:\Windows\system32\REGSVR32.EXE" /u /n /i:"%1" "C:\Windows\system32\scrobj.dll"
HKEY_CLASSES_ROOT\WSFFile
(默認) REG_EXPAND_SZ Windows Script File
FriendlyTypeName REG_EXPAND_SZ @%SystemRoot%\System32\wshext.dll,-4801
HKEY_CLASSES_ROOT\WSFFile\DefaultIcon
(默認) REG_EXPAND_SZ %SystemRoot%\System32\WScript.exe,2
HKEY_CLASSES_ROOT\WSFFile\Shell
(默認) REG_SZ Open
HKEY_CLASSES_ROOT\WSFFile\Shell\Edit\Command
(默認) REG_EXPAND_SZ "%SystemRoot%\System32\Notepad.exe" %1
HKEY_CLASSES_ROOT\WSFFile\Shell\Open\Command
(默認) REG_EXPAND_SZ "%SystemRoot%\System32\WScript.exe" "%1" %*
HKEY_CLASSES_ROOT\WSFFile\Shell\Open2
(默認) REG_EXPAND_SZ Open &with Command Prompt
MUIVerb REG_EXPAND_SZ @%SystemRoot%\System32\wshext.dll,-4511
HKEY_CLASSES_ROOT\WSFFile\Shell\Open2\Command
(默認) REG_EXPAND_SZ "%SystemRoot%\System32\CScript.exe" "%1" %*
HKEY_CLASSES_ROOT\WSFFile\Shell\Print\Command
(默認) REG_EXPAND_SZ "%SystemRoot%\System32\Notepad.exe" /p %1
HKEY_CLASSES_ROOT\WSFFile\ShellEx\ContextMenuHandlers\OpenGLShExt
(默認) REG_SZ {E97DEC16-A50D-49bb-AE24-CF682282E08D}
HKEY_CLASSES_ROOT\WSFFile\ShellEx\DropHandler
(默認) REG_SZ {60254CA5-953B-11CF-8C96-00AA00B8708C}
HKEY_CLASSES_ROOT\WSFFile\ShellEx\PropertySheetHandlers\WSHProps
(默認) REG_SZ {60254CA5-953B-11CF-8C96-00AA00B8708C}
HKEY_CLASSES_ROOT\VBSFile
FriendlyTypeName REG_EXPAND_SZ @%SystemRoot%\System32\wshext.dll,-4802
(默認) REG_SZ VBScript Script File
HKEY_CLASSES_ROOT\VBSFile\DefaultIcon
(默認) REG_EXPAND_SZ %SystemRoot%\System32\WScript.exe,2
HKEY_CLASSES_ROOT\VBSFile\ScriptEngine
(默認) REG_SZ VBScript
HKEY_CLASSES_ROOT\VBSFile\ScriptHostEncode
(默認) REG_SZ {85131631-480C-11D2-B1F9-00C04F86C324}
HKEY_CLASSES_ROOT\VBSFile\Shell
(默認) REG_SZ Open
HKEY_CLASSES_ROOT\VBSFile\Shell\Edit\Command
(默認) REG_EXPAND_SZ "%SystemRoot%\System32\Notepad.exe" %1
HKEY_CLASSES_ROOT\VBSFile\Shell\Open\Command
(默認) REG_EXPAND_SZ "%SystemRoot%\System32\WScript.exe" "%1" %*
HKEY_CLASSES_ROOT\VBSFile\Shell\Open2
(默認) REG_EXPAND_SZ Open &with Command Prompt
MUIVerb REG_EXPAND_SZ @%SystemRoot%\System32\wshext.dll,-4511
HKEY_CLASSES_ROOT\VBSFile\Shell\Open2\Command
(默認) REG_EXPAND_SZ "%SystemRoot%\System32\CScript.exe" "%1" %*
HKEY_CLASSES_ROOT\VBSFile\Shell\Print\Command
(默認) REG_EXPAND_SZ "%SystemRoot%\System32\Notepad.exe" /p %1
HKEY_CLASSES_ROOT\VBSFile\ShellEx\ContextMenuHandlers\OpenGLShExt
(默認) REG_SZ {E97DEC16-A50D-49bb-AE24-CF682282E08D}
HKEY_CLASSES_ROOT\VBSFile\ShellEx\DropHandler
(默認) REG_SZ {60254CA5-953B-11CF-8C96-00AA00B8708C}
HKEY_CLASSES_ROOT\VBSFile\ShellEx\PropertySheetHandlers\WSHProps
(默認) REG_SZ {60254CA5-953B-11CF-8C96-00AA00B8708C}
檢索可引用類型庫的方法
除了以上這種查注冊表的方法姥芥,盡管這個不太優(yōu)雅, 但確實是最根本的方法, 以下提到的所有工具都是依據(jù)注冊表查詢實現(xiàn)的.
第一個工具就是 Visual Studio 97 自帶的 Visual Basic 5.0, 新建一個項目, 在 Project 工程菜單下找到引用 Reference, 在引用對話框里羅列了當前系統(tǒng)已注冊的類型庫, 勾選需要的目標, 然后保存工程, 再用記事本打開工程文檔 vbp, 里面會相關(guān)的類型庫信息, 把GUID復(fù)制過來就可以使用. 注意, Microsoft Office 12.0 Object Library 和 Microsoft Word 12.0 Object Library 是兩個不同的庫兔乞, 后者才是 Word 類型庫, 可以用它來自動化DOC問檔處理, 同樣 Excel, Access 等也是, VBA 是辦公自動化的根基:
Reference=*\G{EF404E00-EDA6-101A-8DAF-00DD010F7EBB}#5.0#0#..\..\VB5EXT.OLB#Microsoft Visual Basic Extensibility
Reference=*\G{2DF8D04C-5BFA-101B-BDE5-00AA0044DE52}#2.4#0#..\..\..\..\Common Files\Microsoft Shared\OFFICE12\MSO.DLL#Microsoft Office 12.0 Object Library
Reference=*\G{00020905-0000-0000-C000-000000000046}#8.4#0#..\..\..\..\Microsoft Office\Office12\MSWORD.OLB#Microsoft Word 12.0 Object Library
Reference=*\G{00025E01-0000-0000-C000-000000000046}#4.0#0#..\..\..\..\Common Files\Microsoft Shared\DAO\DAO350.DLL#Microsoft DAO 3.5 Object Library
第二個工具是 Visual C++ 5.0 自帶的 OLE/COM Object Viewer, 打開 View 視圖下的 Expert Mode 專家模式, 可以翻看各種COM組件, 完全理解羅列的內(nèi)容需要微軟的COM基礎(chǔ).
第三個是 PrimalScript, 這也是一個專業(yè)的通用語言IDE, 看它支持的語言列表就覺得廠家花了大工夫的, 用它寫腳本真的可以省力氣, 如果安裝了SDK, 用它開發(fā)也是不錯的選擇. 集成了FTP這樣實用的工具, 也支持源代碼管理工具 Microsoft SourceSafe 方便團隊合作.
在右側(cè) Workspace Browser 中彈出右鍵菜單, 可以建立新工程, 也可以在已有的腳本工程中設(shè)置屬性, 還可給job添加 object, reference 等:
Visual Basic 和 PrimalScript 都有對象瀏覽器, 可以用來查詢對象的結(jié)構(gòu).
使用對象瀏覽器的一個好處是可以查看類一些詳細的信息, 如 Scripting.FileSystemObject 的幾個常數(shù)定義:
+--CompareMethod
| +--BinaryCompare=0
| +--TextCompare=1
| +--DatabaseCompare=2
+--IOMode
| +--ForReading=1
| +--ForWriting=2
| +--ForAppending=8
+--Tristate
+--TristateTrue
+--TristateFalse=0
+--TristateUseDefault=-2
+--TristateMixed=-2
這些常數(shù)只需要在 wsf 中加入引用即可以訪問:
<object id="fso" progid="Scripting.FileSystemObject" events="true"/>
玩 Visual Studio 97 時發(fā)現(xiàn)自帶一個 MIDI 合成小玩具 Music Producer:
WSF 的一些小技巧
通過右鍵設(shè)置 wsf 腳本文件的屬性,系統(tǒng)會自動生成 wsh 配置文件凉唐,內(nèi)容大概如下:
[ScriptFile]
Path=E:\coding\coding.wsf
[Options]
Timeout=10
DisplayLogo=0
為了交叉調(diào)用, 需要安裝 MSScriptControl, 下面的例子演示在 JScript 中調(diào)用 VBScript 的 InputBox:
// this require MSScriptControl
function(){
var scriptCtrl = new ActiveXObject("MSScriptControl.ScriptControl");
scriptCtrl.Language = "VBScript";
this.prompt = function(msg) {
return scriptCtrl.Eval(
'InputBox(unEscape("' + escape(msg) + '"), "Input")'
);
};
}
wsf 可以有多個 job 定義, 單個 job 可以不使用 package, 執(zhí)行腳本時第一個 job 會被執(zhí)行庸追,可以在命令行執(zhí)行指定 job 的代碼:
CScript //Job:IncludeExample //Job:MoreExample MyScripts.wsf
wsf 元素介紹
<?job?>元素 用于指定錯誤處理屬性的 XML 處理指令。
<?XML?>元素 表示文件應(yīng)作為 XML 進行分析台囱。
<description> 元素 對用戶運行 ShowUsage() 或運行帶有 /? 命令行時出現(xiàn)的描述淡溯。
<example> 元素 使腳本具有自我說明性。
<job> 元素 在 Windows 腳本文件 (*.wsf) 中標記作業(yè)的開始和結(jié)束簿训。
<named> 元素 對腳本的特定命名參數(shù)進行標記咱娶。
<object> 元素,可用在 Windows 腳本組件文件中强品,并定義可由腳本引用的對象膘侮。
<package> 元素 將多個作業(yè)定義放在 Windows 腳本宿主控制文件 (.wsf) 中。
<reference> 元素 用于包括對外部類型庫引用的 XML 元素的榛。
<resource> 元素 用于隔離不應(yīng)硬編碼到腳本中的文本數(shù)據(jù)或數(shù)值數(shù)據(jù)的 XML 元素琼了。
<runtime> 元素 將某個腳本的一系列運行時參數(shù)組合起來。
<script> 元素 包含用于定義 Windows 腳本組件行為的腳本的 XML 元素夫晌。
最重要的事, WSF是一個XML文檔, 而腳本語言中的邏輯運算符 < 或 > 等會引起XML標記的沖突, 因此一定記得使用 CDATA 將腳本包裹起來, 不然調(diào)試器給的信息不沾邊, 半天找不出原因, 我試過兩會了:-(
<![CDATA[
// scripting here ...
]]>
完整的wsf例子:
<?XML version="1.0" standalone="yes" ?>
<package>
<job id="ScriptMe" args="arg1 arg2" prompt="no">
<?job error="false" debug="false" timeout="30" ?>
<runtime>
<description>Let us study Windows Script Host </description>
<unnamed helpstring="the first one" name="UnamedArg" required="10"/>
<named helpstring="some help" name="arg1" required="true" type="boolean"/>
<named helpstring="some help about a2" name="arg2" required="true" type="string"/>
<named helpstring="some text about it" name="arg3" required="false" type="simple"/>
<example>Run it as you want to and test it as you like</example>
<usage>This is a scripting demo </usage>
</runtime>
<reference id="Microsoft Visual Basic 5.0 Extensibility" guid="{EF404E00-EDA6-101A-8DAF-00DD010F7EBB}" version="5.0"/>
<reference id="Microsoft WinHTTP Services, version 5.1" guid="{662901FC-6951-4854-9EB2-D9A2570F2B2E}" version="5.0"/>
<reference id="Microsoft Script Control 1.0" guid="{0E59F1D2-1FBE-11D0-8FF2-00A0D10038BC}" version="1.0"/>
<object id="word" progid="Word.Application" events="true"/>
<object id="fso" progid="Scripting.FileSystemObject" events="true" reference="true"/>
<object id="encoder" progid="Scripting.Encoder" events="true" reference="true"/>
<script language="JScript" src="vbconst.js"/>
<script id="vba" language="VBScript">
<![CDATA[
MsgBox "VB Const vbAbort=" & vbAbort
word.Quit
' define function for jscript
Function ShowBox(msg)
showBox = InputBox(msg, "Tip")
End Function
Function messageBox (msg, style, title)
MsgBox msg, style, title
End Function
]]>
</script>
<script id="js" language="JScript">
<![CDATA[
// demo procedures programming
function write(msg){
WScript.echo(msg);
}
var global="GLOBAL";
messageBox ("Test MsgBox in JScript", vbYesNoCancel|vbExclamation, "Tip");
write("Test FileSystemObject const ForAppending:"+ForAppending);
write("Test for script include:"+test());
var ret = showBox("Test VBScript in JScript");
write("Test VBScript in JScript & showBox return: "+ (!ret? "User Cancel":ret) );
]]>
</script>
<script id="vba" language="VBScript">
<![CDATA[
'call function from script file ...
write("Test acess variable global="+global)
write("Test JScript in VBScript:"+WScript.version)
]]>
</script>
<script id="oop" language="JScript">
<![CDATA[
// demo object-oriented programming
function Base(){
var p = "I'm yours"
this.action = function(){
write("public function access private member: "+p);
}
}
var a = new Base();
a.action();
]]>
</script>
</job>
<job id="WordInScripting">
<?job error="false" debug="true" ?>
<script language="JScript">
<![CDATA[
var Word, Doc, Uncorrected, Corrected;
var wdDialogToolsSpellingAndGrammar = 828;
var wdDoNotSaveChanges = 0;
Uncorrected = "Helllo world!";
Word = new ActiveXObject("Word.Application");
Doc = Word.Documents.Add();
Word.Selection.Text = Uncorrected;
Word.Dialogs(wdDialogToolsSpellingAndGrammar).Show();
if (Word.Selection.Text.length != 1)
Corrected = Word.Selection.Text;
else
Corrected = Uncorrected;
Doc.Close(wdDoNotSaveChanges);
Word.Quit();
//write("not calling between jobs");
]]>
</script>
</job>
</package>
腳本還可以編寫腳本組件, Windows Script Components, WSC文件也是XML格式, 通過各種元素來實現(xiàn)COM規(guī)范組件, 簡單說就是用腳本編寫 COM 組件, JScript 也可以像 Visual Basic 一樣寫 COM 組件. 這個似乎很厲害呢, 看參考文檔去吧, 這里不深入了. 使用 PrimalScript 的 WCF Wizard 可以快速建立一個腳本組件模板. 提示一點, MSDN 內(nèi)容雖然豐富, 但是沒有對應(yīng)的基礎(chǔ), 很容易看迷糊的, 這時就需要好好想想去補習(xí)基礎(chǔ)了.
比如說 Visual Studio 97 中 ActiveX SDK 就提供了一個 WebPost API, WebPost 這個貨就是用來做 HTTP 文件上傳的. 如果弄懂了 HTTP 協(xié)議, 上傳文件是個輕松活, 可是一頭扎進 MSDN 就不容易弄懂了. 因為每個API都是人寫的, 每個人思維模式都不一樣, 另外整理MSDN文檔的人也沒有義務(wù)把清晰的思路整理出來給你, 他們做的只是技術(shù)文檔, 這個文檔能用來說明什么是什么就夠了, 所以參考MSDN也是需要一個方法論來指導(dǎo)的. 而且 WebPost 本身是建立在基礎(chǔ)架構(gòu)之上的, 沒有這些架構(gòu)的基礎(chǔ), 理解起來就是件麻煩. 作為一個有經(jīng)驗的 Web 開發(fā)者, 我看到 WebPost 參考文檔時也是覺得頭大的, 所以我不信你不會:
+--WebPost API Functions
| +--WpBindToSite
| +--WpDeleteSite
| +--WpListSites
| +--WpPost
| +--WpPostFile
+--WebPost API Structures
| +--WPSITEINFO
+--WebPost SPI Functions
| WppBindToSite
| WpBindToSite
| WppListSites
+--WebPost SPI Interface Functions
+--AddWizardPages
+--Commit
+--DeleteFile
+--FindClose
+--FindFirstFile
+--FindNextFile
+--GetError
+--GetParam
+--GetSiteInfo
+--NetWorkConnect
+--PostFiles
+--ServerLogin
+--ServerLogout
+--SetParam
另外, 我也相信 WebPost 就是一個挖出來的坑, 并不是那么好用的東西, 我用 JScript 腳本可以做的事就不必搞什么 SDK 了, 如果再費時點, 那可以選擇 C 語言自己寫一個嘛.
參考文檔
強烈推薦Microsoft Windows腳本技術(shù), 英文版 script56.chm 內(nèi)容更新更齊全, 特別是關(guān)于正則表達式的內(nèi)容, 這部分內(nèi)容很豐富, 值得另取一文講解. 還有Advanced Windows Script Host Developers Guide 這本書深入講解了Windows腳本編程技術(shù), 腳本與應(yīng)用程序的交互, 配合 Visual Basic 開發(fā)的 ActiveX 組件來擴展腳本功能. 書中舉例 JScript 實現(xiàn) VBScript 的 InputBox 功能, 通過 Internet Explorer 組件加載頁面來模擬, 又可以通過開發(fā) ActiveX 來實現(xiàn), 使用 wsf 集合 VBScript 和 JScript 來實現(xiàn), 甚至更直接地使用 WScript.Shell 的 Environment 屬性實現(xiàn)通過環(huán)境變量來傳遞數(shù)據(jù).
還有一本資料《Advanced Development with Microsoft Windows Script Host 2.0》, 看標題應(yīng)該是深層次的數(shù), 可惜找不到資源. 此外雕薪,SAPIEN 即 PrimalScript 發(fā)行公司初版的以本書是《WSH and VBScript Core 》。
微軟官方早期的 MSDN 也可以作為參考, 在 Microsoft Visual 97 下載鏈接中可以找到.
Admin Script Editor Enterpise 3.1
PrimalScript 2014_7.0.32 x86
epp500_0651_smart.exe
《Microsoft Windows Script Host 2.0 Developer's Guide》 scripthost20dev.chm
《Advanced Windows Script Host Developers Guide (2003)》
Microsoft Windows腳本技術(shù)
Microsoft Windows Script Technologies script56.chm
Microsoft Visual 97 我喜歡的
Microsoft Visual 97 加密分享: 9km8