WSH 的檔案類型
除了 .vbs、.js 之外,WSH 還有 .wsf 和 .wsh 兩種檔案類型,而這四種檔案類型都是純文字格式。.wsf 是 WSH 2.0 所新增的副檔名,這種類型最大的優點是可以包含其他 .vbs或.js 程式,是 WSH 的專案檔。上述三種類型都是 WSH 程式,它們利用 WSH 環境、直譯器在執行;而 .wsh 則是儲存 WSH 程式執行參數的檔案。
.wsh 類似 Windows 的捷徑,試著想像一種情況:某個 Windows 程式可以根據不同的命令列執行參數,而有不同的執行方式,如果不想每次執行都輸入繁瑣的執行參數,當然就是替每種執行參數建立捷徑,不同的捷徑啟動不同參數的執行方式。同樣的,WSH 程式也可以有數種不同的執行參數,如果每次執行都得重新調整執行參數,著實麻煩累人,但是只要利用不同的 .wsh 檔案,就可以記錄同一個 WSH 程式的各種執行參數。
只要以滑鼠右鈕按下 WSH 程式,再選取快顯功能表中的「內容」,便可以調整 Scripting Host 執行 WSH 程式的執行參數。假設您在執行某個 WSH 程式時,經常需要更改 WSH 程式的終止時間參數,除了每次執行 WSH 程式之前,都開啟交談窗來修改之外,最好的方法應該是替不同的終止時間建立不同的 .wsh 檔案。
只要您利用上述的交談窗修改了 WSH 程式的執行參數,Windows 系統便會自動建立一個主檔名與 WSH 程式的主檔名相同,但副檔名為 .wsh 的 WSH 程式設定檔。但是請特別注意,如果 WSH 程式的設定檔已經存在,那麼新的設定值會蓋掉舊的設定值,因此如果想要保留舊的設定檔,請記得一定要先更改設定檔的主檔名,再利用交談窗來調整。.wsh 檔案的格式非常類似 .ini 或 .inf 檔,而且結構非常簡單。
編寫 WSH 程式初步
WSH 程式跟一般的 script 程式一樣,都是純文字檔,因此您可以利用文字編輯程式來編寫 WSH 程式,而許多文字編輯程式都會提供更多便利的功能,協助編寫 script 程式;例如我所慣用的 EmEditor 便支援 WSH 程式的三種類型。
這裡有個簡單的 WSH/VBScript 程式(WSHInfo.vbs),會以交談窗顯示 WSH 執行環境的版本、路徑及程式檔名,以及 WSH 程式的路徑和程式檔名等相關資訊:
' WSHInfo.vbs 顯示 WSH 的若干訊息
Option Explicit
Dim strHostName,strHostFullPathName,strScriptFullName
Dim strMessage
strHostName = WScript.Name & " " & WScript.Version & vbCrLf
strHostFullPathName = "目前的 WSH 程式是由 " & WScript.FullName &
"所執行" & vbCrLf
strScriptFullName = "所執行的 WSH 程式是 " & WScript.ScriptFullName
strMessage = strHostName & vbCrLf & strHostFullPathName &
vbCrLf & strScriptFullName
MsgBox strMessage, vbInformation, "WSH 相關訊息"
.wsf 的格式比 .vbs 或 .js 略微複雜,因為 .wsf 採用了 XML 格式,因此也新增了專屬的標籤(tag);以下將說明基本的四個標籤:<package>、<job>、<object>、<script>(完整的資料請參照 WSH 說明文件)。必須提醒您的是,這些標籤僅適用於 .wsf 檔案,如果您是以 .vbs 或 .js 製作 WSH 程式,就不能替程式加入這些標籤,否則就會出現錯誤訊息。
只要以<script>標籤加以區隔,.wsf 就可以混合使用多種描述語言:
<script language="VBScript">
程式碼
</script>
或
<script language="JavaScript">
程式碼
</script>
在.wsf 檔案中,程式都必須放在<script>區段,並且以標註程式的描述語言名稱。<script>標籤還有另一個 src 屬性,透過這個屬性,可以達到類似 C 語言的 include 功能。也就是說,src 屬性可以引入其他的 JavaScript 程式或 VBScript 程式,並且執行,例如:
<script language=”JavaScript” src=”getInfo.js”/>
此外,每個 .wsf 檔案至少必須包含一個<job>區段。<job>區段是 WSH 程式的最小執行單位。如果 .wsf 檔案只有一個<job>區段,那麼 .wsf 檔案執行時,其實就是執行這唯一的一個<job>區段:
<job>
<script language="script名稱">
程式碼
</script>
</job>
.wsf 檔案也可以包含數個<job>區段,不過像這種情況,有幾件事必須特別注意。首先,必須有一對<package>標籤括住所有的<job>區段,而且每個 .wsf 檔案也只能有一對<package>標籤。其次,在有數個<job>區段的情況之下,每個<job>區段就必須利用<job>標籤的 ID 屬性替<job>區段命名。
之前提過<job>區段是 WSH 程式的最小執行單位,而每次執行 .wsf 檔案,其實是執行 .wsf 檔案<job>區段的程式碼。但是在同時擁有數個<job>區段的情況之下,WSH 執行環境會執行那個<job>區段呢?這可以由使用者透過 WSH 執行環境(也就是 WScript 或 CScript)的 //Job 選項來指定,假設 jobs.wsf 裡面有兩個<job>:
<package>
<job id="CopyFile">
<script language="script 名稱">
程式碼
</script>
</job>
<job id="DelFile">
<script language="script 名稱">
程式碼
</script>
</job>
</package>
如果要以 CScript 搭配 //Job 選項來指定所要執行的 <job>,下列第一行指定要執行 CopyFile,第二行則指定要執行 DelFile:
CScript //Job:CopyFile jobs.wsf
CScript //Job:DelFile jobs.wsf
如果 .wsf 檔案裡面擁有數個 <job> 區段,但卻沒有利用 //Job 選項指定 <job> 區段,那麼 WSH 執行環境會以 .wsf 檔案裡面的第一個 <job> 區段,作為預設執行的 <job> 區段。
<object> 標籤的用途是讓我們可以在同一個 <job> 區段的各個 <script> 區段共用某個物件。由於 WSH 並沒有全域變數,因此如果在 <job> 區段的各個 <script> 區段都需要用到某個物件,勢必無法將物件指定給全域的物件變數,而必須在各個 <script> 區段都以 WScript.CreateObject 方法自行建立相同的物件,但如果真的這麼做的話,實在是相當耗用系統資源。
而 <object> 的作用相當類似全域物件變數,如果您需要在同一個 <job> 區段的各個 <script> 區段使用相同的物件,就可以先利用 <object> 標籤宣告物件,便可以在各個 <script> 區段內共用同一個物件了。