建立小工具:第一篇

Windows Vista

下文是根據 Microsoft Windows Vista 作業系統發行前版本寫成。這表示文中討論的功能可能會有所異動:某些功能可能會因行銷、技術或其他因素而不包含在最終產品中。如果發生這類變更,我們將盡全力更新本文內容。

本页内容

得獎人是...
Microsoft 小工具 (超短) 簡介
建立你的首件小工具
Gadget 資料夾
資訊清單檔
HTML 檔案
在 <SPAN> 中顯示資料
建立「自動執行」的小工具
建立「自動重新整理」的小工具
下一篇精彩預告


得獎人是...

每年至少有一部電影提名角逐六、七項奧斯卡金像獎,包括所有重要獎項:最佳影片、最佳導演、最佳男主角、最佳女主角。真的很不錯!只可惜總是會有些參與盛會的大老闆,發現自己坐在奧斯卡頒獎典禮的觀眾席上,禮貌性地假裝微笑、鼓掌,眼看著別人的電影抱走所有重要獎項。最佳影片還是最佳導演?嗯,都不是,不過我們得了最佳錄音音效和最佳服裝設計。

嗯...不錯...

指令碼作者對這種感覺再熟悉不過了,每次宣佈新的作業系統時,指令碼作者就閉上眼睛坐著,雙手手指交叉,滿心期待這次總有一項重要宣佈是衝著他們而來。但是每次新的作業系統宣佈時,指令碼作者總免不了大失所望。當然,總是會有新的 Windows Management Instrumentation (WMI) 類別和一些新的 COM 物件可以玩玩,是不錯啦:新玩意兒總是多多益善。只可惜,弄那麼幾個新 WMI 類別實在有點像贏得最佳錄音音效獎:雖然很高興贏得獎項,但看著別人抱走真正了不起的大獎,多少總會覺得若有所失。一次就好,真希望也能贏得一次大獎,真希望有那麼一次最先進的創新發明是衝著你來!最佳錄音音效棒是棒,可是真希望能有一次贏得最佳影片或最佳導演。

你也許還不知道,但如果你是指令碼作者,一輩子等待的良機就是 Windows Vista。

Microsoft 小工具 (超短) 簡介

傳聞絕對屬實。Windows Vista 充滿各式各樣的新鮮玩意兒,其中最酷、最讓人期盼的功能就是 Windows 資訊看板 (Sidebar),這是專門針對指令碼作者而設計的。Windows 資訊看板是特別為「小工具」保留的螢幕區,跟「快速啟動」列類似在於,它也是在螢幕上保留一區供捷徑使用。小工具是迷你應用程式,少少幾行程式碼,就能完成小工具原創人想要達到的目標。例如,Windows Vista 推出就會附上一些小工具,包括基本的小計算機和一對監視 RSS 摘要的小工具。新社群也圍繞著小工具如雨後春筍般成立,如需詳細資訊 (並下載社群成員所建立的小工具),請參閱 Microsoft Gadgets網站。不消多久,稍一瀏覽小工具庫,您就能瞭解小工具有多棒、有多酷!

但我們要承認事實:這世界上也充滿其他人能創造的新酷東西。真正讓 Gadget 異軍突起而讓人興致勃勃的是:這項新技術是完全為指令碼作者而設計的。不過可別搞錯:小工具是很棒,很酷!它有那種先進科技的感覺,而且小工具也確實能夠完成一些非常複雜的工作。可是,在酷炫流行的外表底下,小工具說穿了不過是迷你型的 HTML 網頁:將簡單的 HTML 網頁湊在一起,加點 VBScript 程式碼 (包括 WMI 程式碼),再摻點小工具物件模型 (本系列文章第二篇會更深入探討),就完成了全新的小工具。小工具是 Windows Vista 其中一項熱門新功能,而指令碼作者就是開始創作這些小工具的人。

這實在是個很棒的點子。也許是該少說多做了!我們來看看,能不能協助您自行完成您的小工具處女作。

建立你的首件小工具

針對 Microsoft 而發的批評之一 (沒錯!信不信由你,確實有人這樣批評過 Microsoft) 是:我們有很多產品很顯然是特別設計供機器人或 Omicron IV 星球上的外星人使用,反正,總而言之,這些產品並不是設計供一般人使用的。好消息!Microsoft 小工具絕對不是這樣 (不過,如果你碰巧就是機器人或是來自 Omicron IV 星球的外星人,別擔心!保證你一樣能夠輕鬆自如地創造小工具)。要建立小工具,你只需要兩樣東西:

  • 一個「資訊清單」檔案 - Gadget.xml。這份資訊清單包含小工具的所有設定,包括小工具名稱、作者和著作權資訊,以及實際組成小工具的 HTML 網頁相關資訊。

  • 一個 HTML 檔 例如,Test.htm)。雖然小工具外表看起來一點都不像,但其實骨子裡就是 HTML 檔案:只要建立一個 HTML 檔,加上適當的標記和指令碼,你的 Gadget 就完成了!

附註:是!我們知道你根本不懂所謂「適當的標記和指令碼」到底是什麼?放心好了!這就是本文以下要說明的。


要建立小工具就只需要這兩樣。確實沒錯!當你建立更加複雜的小工具時,就會發現要處理圖示檔案、圖形檔案、設定值檔案,以及其他元素。但是慢慢來,船到橋頭自然直。

你看,夠簡單的吧?啊?「是啊,目前來說」?你說得沒錯:這時候似乎是你該做一些極其複雜的處理的時候,可能要使用一些專利的編譯器,Scripting Guys 可能會以美金 39.95 塊錢的價格賣給你,外加運費和處理費 (說得也是,你這麼一說,倒希望我們當初想到這麼一招)。但是現在你不必使用那些專利編譯器,只要如下收集所有檔案,然後再「編譯」成小工具就好了:

  1. 將所有檔案放在 Gadget 資料夾中。

就是這樣:將所有檔案放入資料夾中,你的小工具就完成了。不必編譯,不需要編譯器,只要將檔案複製到指定的資料夾,再沒有任何煩瑣或技術性的作業!

哦!附帶一提,如果您還是願意寄 39.95 塊美元給我們,我們會很樂意地收下。

Gadget 資料夾

當然,凡事總少不了一點小麻煩:你不能將檔案隨便放進任何舊資料夾裡頭。而是要按照下列程序逐步執行:

先從啟動 Gadgets 資料夾開始。迅速存取 Gadgets 資料夾的方法之一是,在 [執行] 對話方塊中輸入下列命令:


%userprofile%\appdata\local\microsoft\windows sidebar\gadgets


附註:什麼?找不到 [開始] 功能表上的 [執行] 命令?不好意思,差點忘了,為了某些原因,這個命令按照預設會隱藏起來。不過沒關係,如果要叫回 [執行] 命令,只要用滑鼠右鍵按一下 [開始] 按鈕,然後按一下 [內容] 就行了。在 [開始功能表] 索引標籤上的 [工作列及開始功能表內容] 對話方塊中,按一下 [自訂]。

到現在都沒問題吧?很好。進入 [自訂開始功能表] 對話方塊之後,向下捲動,然後勾選 [執行命令] 核取方塊。按個幾次 [確定],[執行] 命令就會回到該出現的位置上。

是的,通常 Scripting Guys 確實要收費美金 39.95 元 ,才會提供這類的內幕消息。不過這次就免費奉送好了!


在 Gadgets 資料夾中建立新資料夾。隨意給這個資料夾取個名字,只要名稱是以 .gadget 副檔名結束就行了 (例如,Test.gadget)。很顯然,如果資料夾名稱跟其中所包含的小工具很類似,那就方便多了!但作業系統只是使用這個資料夾來識別其中組成小工具的檔案,小工具名稱是從資訊清單中找到的資訊衍生而來,而不是從資料夾名稱衍生而來 (Scripting Guys 是撞得頭破血流才發現這個道理)。

現在你只需要將所有檔案 (例如 Gadget.xml 和 Test.htm) 放進資料夾就行了。這不就表示你已經有一個 Microsoft Gadget 了嗎?沒錯,就是這樣。其實執行 Windows 資訊看板以後,按一下 + (加號) 按鈕,啟動在你電腦上找到的小工具集,你的小工具就會顯示在小工具選擇器對話方塊中。

附註:什麼?你也找不到 Windows 資訊看板?那有什麼問題?如果找不到 Windows 資訊看板,就執行下列步驟:按一下 [開始] 功能表 > [所有程式] > [附屬應用程式],你應該就會看到資訊看板的連結。


安裝小工具

假定你的小工具真的確實顯示在可用的小工具清單中,你就可以將圖示拖曳到 Windows 資訊看板上,然後放開滑鼠按鍵,就可以安裝小工具了 (也可以用滑鼠右鍵按一下小工具圖示,再按一下 [新增])。這時候就會顯示小工具,你就可以開始使用了。如果你決定要從資訊看板移除小工具,只要在小工具上按住滑鼠按鍵,然後按一下顯示在右上角的小 X,就可以移除。如果不確定我們指的是哪個小 X,哪!就是這個:

Microsoft Gadget

資訊清單檔

前面已經說過了,如果要建立小工具,你需要兩樣東西:一個資訊清單檔和一個 HTML 檔。我們知道讀者在想什麼:當然啦,在 Omicron IV 星球上你們大概無時無刻不使用資訊清單檔 (我們有些人用,有些人不用)。但是系統管理員對資訊清單檔有什麼瞭解?

嗯,這麼說吧,你應該知道 (以前不知道,至少現在是知道了):「資訊清單檔」根本就是自以為了不起地賣弄專門術語,其實指的就是一些 .INI 檔、簡單的文字檔 (在這裡是以 XML 建立的文字檔),其中包含小工具的設定資訊。無可否認地,想到必須要用 XML 撰寫,可能會讓你背脊骨有點發涼。嘿,別擔心!這將是你所應付的最簡單、最起碼的 XML 檔案。

舉個例子給你看:


<?xml version="1.0" encoding="utf-8" ?>

<gadget>
    <name>My First Gadget</name>
    <author>The Microsoft Scripting Guys</author>
    <copyright>2006 Microsoft Corporation</copyright>
    <description>Sample gadget that returns the name of the installed operating system.</description>
    <icons>
        <icon>icon.png</icon>
    </icons>
    <version value="1.0.0.0" MinPlatformVersion="0.1"></version>
    <sidebar>
        <type>html</type>
        <permissions>full</permissions>
        <code>test.htm</code>
        <website>www.microsoft.com/technet/scriptcenter</website>
     </sidebar>
</gadget>


你不用問,是的,你可以直接複製這個檔案,就這樣幾乎原封不動地使用,只要稍稍 (視需要) 改變一些標記值就行了 (還有,別忘了!必須將檔案命名為 Gadget.xml)。你可能要或必須要修改的標記就在下表中指定:

標記

說明

<name>

顯示在小工具選擇器對話方塊中的小工具名稱。

<author>

小工具作者的姓名。按一下特定小工具時,作者、著作權和說明標記都會顯示在小工具選擇器中。如需詳細資訊,請參閱下面顯示的圖例說明。

<copyright>

著作權資訊,包括著作權所有人姓名和著作權日期。

<description>

小工具的簡要說明及其作用。

<icon>

圖示檔案的名稱 (圖示是顯示在小工具選擇器中的圖形)。如需有關圖示的詳細資訊,請參閱本文件下列小節中的<建立圖示>。

<code>

大概不是很直覺式的標記名稱,但這是組成你的小工具的 HTML 檔名稱。

<website>

與小工具相關聯的網站。


為了更清楚、更簡潔地說明這些標記,下面就把資訊清單元素逐一對應到小工具選擇器對話方塊中所顯示的項目:

Microsoft Gadget


建立圖示

是否要提供小工具的自訂圖示,完全由你決定,如果不提供圖示 (或者說,如果不在資訊清單檔中指定圖示),小工具選擇器會提供預設圖示 (不另外加收費用)。

如果你確實決定要提供自訂圖示,請牢記!「圖示」只是一般的舊影像檔的名稱,這些並不是真正的 Windows 圖示,那是必須用特殊軟體建立的圖形。這裡的圖示只是圖片檔,不管是 .GIF、.JPG 或 .PNG 圖形都行。Windows Vista 隨附的範例小工具全部都是使用 .PNG 圖形,大概是因為 .PNG 圖形允許透明背景,讓你能夠製作很酷的圖片 (假定你有藝術天份)。但是,你不必將圖示存成 .PNG 檔。你可以改載入小畫家,建立圖示,存成 .JPG 檔,你的圖示將顯示在小工具選擇器裡,完全沒有問題。

問得好:圖示應該多大?理想的大小是 64 像素乘以 64 像素。小工具選擇器會將你的影像調整為最適大小,但是如果小工具選擇器需要縮小或拉長影像以配合所配置的空間時,一開始就建立 64x64 圖示有助於防止影像失真。

如果你想知道,這是本文所使用的圖示:

Microsoft Gadget


我們也蠻喜歡的。

附註:你可能也注意到了,在資訊清單檔裡,<ICON> 標記是內嵌於 <ICONS> 標記之中:

<icons>
    <icon>icon.png</icon>
</icons>

這表示你可以新增其他圖示到資訊清單檔中嗎?大概是可以,不過,老實說,我們實在不知道你要另外用其他圖示做什麼。不過我們會探究一番。


HTML 檔案

組成小工具本身的 HTML 檔案其實跟任何使用動態 HTML 的網頁沒什麼兩樣,說實在的,如果要建立 HTML 檔,只要使用任何有效的 HTML 標記法 (包括 CSS 樣式) 加上指令碼就行了。我們馬上就會樣本 HTML 網頁範例給你看。不過在示範以前,我們必須稍稍離一下正題,談談怎麼在小工具裡頭納入 WMI 程式碼。

使用 WMI

身為系統管理員,你很習慣撰寫指令碼,大量使用 WMI。這是很合理的作法,畢竟 WMI 技術可用來協助您管理從印表機到磁碟機,從滑鼠到監視器的一切。WMI 最大的好處是很容易使用。例如,假設你想知道安裝在本機電腦上的作業系統名稱。沒問題,以下的 WMI 指令碼可以傳回這項資訊給你:


strComputer = "."

Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

Set colItems = objWMIService.ExecQuery("Select * From Win32_OperatingSystem")

For Each objItem in colItems
    Msgbox objItem.Caption
Next


如果你計劃要建立小工具用於系統管理,我們得告訴你一些壞消息:你從前習慣撰寫的 WMI 指令碼在小工具裡不能用 (等一下,千萬別魯莽從事:消息馬上就會轉好,我保證)。那是因為,其實小工具的核心就是網頁,而基於安全性的考量,網頁是不能夠使用 GetObject 的。如果你將先前的程式碼放入小工具之中,結果就只會收到如下的錯誤訊息:


ActiveX component can’t create object: 'GetObject'


糟糕...

但是,不必驚慌!你還是可以在小工具之內使用 WMI 指令碼,只是不能使用 GetObject 和 winmgmts:moniker。你必須改用 CreateObject 來建立 WbemScripting.SWbemLocator 物件的執行個體,再用 ConnectServer 方法,連線到 WMI 服務。換句話說,你必須撰寫如下的程式碼:


strComputer = "."

Set objLocator = CreateObject("WbemScripting.SWbemLocator")
Set objWMIService = objLocator.ConnectServer(strComputer, "root\cimv2")

Set colItems = objWMIService.ExecQuery("Select * From Win32_OperatingSystem")

For Each objItem in colItems
    Msgbox objItem.Caption
Next


看吧?我們說過了,不用驚慌 (雖然老實說,這大概也算是我們的錯,是我們先嚇得你們驚慌失色的)。使用 WMI Moniker 的指令碼與使用 ConnectServer 的指令碼之間唯一的差異,是在連線到 WMI 服務時才發生。您很習慣使用單行程式碼來建立連線:


Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")


現在你必須使用兩行程式碼來建立連線 (是的,工作量加倍!):你建立 WbemScripting.SWbemLocator 物件的執行個體,再使用 ConnectServer 方法來繫結到 WMI 服務。請注意,我們傳兩個參數給 ConnectServer:要連線的電腦名稱 (由變數 strComputer 代表) 和我們要連線的 WMI 命名空間 (在本範例中是 root\cimv2):


Set objLocator = CreateObject("WbemScripting.SWbemLocator")
Set objWMIService = objLocator.ConnectServer(strComputer, "root\cimv2")


都瞭解了嗎?很好。現在我們要再回到正題。

建立 HTML 檔

我們前面已經提過,小工具不過是 HTML 檔。也就是說,你在 HTML 網頁中可以使用的任何元素 (包括動態元素),也都可以用在小工具中。你可能也已經猜到,這也包括 VBScript 程式碼,雖然大部份透過 Microsoft Gadgets 網站提供使用的早期小工具都是使用 JScript 或 JavaScript,VBScript 還是很好用 (你馬上就可以看到)。

我們已經示範過一段傳回安裝在本機電腦上作業系統名稱的 WMI 指令碼,舉一反三,我們來看看是否能將這個指令碼變成小工具。我們會從簡單的開始,先建立以單一按鈕組成的小工具,按一下該按鈕,就會在訊息方塊中顯示作業系統 Caption 屬性的值。以下是我們的小工具的 HTML 程式碼:


<html>

<head>
    <title>My First Gadget</title>

    <style>
        body{width:120;height:160}
    </style>

</head>

<script language="VBScript">

    Sub RunSub
        strComputer = "."

        Set objLocator = CreateObject("WbemScripting.SwbemLocator")
        Set objWMIService = objLocator.ConnectServer(strComputer, "root\cimv2")

        Set colItems = objWMIService.ExecQuery("Select * From Win32_OperatingSystem")

        For Each objItem in colItems
            Msgbox objItem.Caption
        Next
    End Sub

</script>

<body>
    <input type="button" value="Run" name="run_button" onClick="RunSub">
</body>

</html>


你可以看到,程式碼裡沒有什麼「小工具特性」,這是基本簡單的 HTML,只是在網頁上顯示一個按鈕,沒有什麼其他作用。按一下該按鈕時,就會執行一個 RunSub 副程式,該副程式接著使用 WMI 來判斷安裝在電腦上的作業系統名稱。

附註:好啦,也許對有些人來說,這是簡單基本的 HTML,可是如果你完全沒有任何編寫 HTML 程式碼的背景怎麼辦?如果是這樣,也許你應該看看我們分成兩部的 HTA 教學課程。這個教學課程可以協助提高你的程度,瞭解諸如 <SCRIPT> 標記和 <INPUT> 標記之類的項目。


在這裡我們唯一需要特別提醒你注意的是 <STYLE> 標記。當我們開始建立比較複雜的小工具時,就會詳細討論 <STYLE> 標記,現在我們只是要指出我們是使用這個標記來設定小工具的預設高度和寬度:


<style>
    body{width:120;height:160}
</style>


這個標記單純是表示,我們要小工具有 120 像素寬 (Windows 資訊看板大約是 130 像素寬) 乘以 160 像素高。在這個特定的小工具裡,160 像素可能會太高,如果是這樣,我們就可以直接指定不同的值給 height 屬性:


<style>
    body{width:120;height:40}
</style>


當你安裝這個小工具時,它在 Windows 資訊看板中的外觀大概如下所示:

Microsoft Gadget


按下按鈕後,會變成這樣:

Microsoft Gadget


沒關係,趕快寫信給媽媽,告訴她好消息,把你所建立的新酷小工具全部說給她聽。寫完了再告訴我們一聲,我們再繼續談別的。

在 <SPAN> 中顯示資料

到現在為止,我們建立的小工具可以在按下按鈕之後,將作業系統名稱顯示在訊息方塊中。這沒什麼不對,將來你一定會有小工具傳回太多資訊的時候,到那時,你沒辦法,只好將這些資訊顯示在訊息方塊、Internet Explorer 視窗,或是其他位置中。

另一方面呢,你遲早會建立出一些使得將資訊顯示在訊息方塊中沒有什麼道理,還有必須按下按鈕才能傳回這些資訊也沒有什麼道理的小工具。例如,假設你決定要為 Windows 資訊看板建立時鐘。那很好啊!可是你真的每次想要知道時間,就必須被迫按一下按鈕嗎?真的按下按鈕時,要讓時間顯示在訊息方塊中嗎?當然,在 Omicron IV 星球上我們是很喜歡這樣做!但是一般人就會覺得有點煩瑣,更何況這實在也有點太蠢了吧!

換句話說,我們需要建立有下列功能的小工具:

  • 在小工具本身界限之內顯示資料。稍後在本系列中,我們會為你示範以圖形顯示這項資訊的方式,但是現在我們就專注探討文字顯示好了。

  • 自動擷取資料,而毋需任何形式的使用者互動作業。

  • 定期更新該資訊。例如,監視電腦上可用記憶體的小工具 (這是我們馬上就會建立的小工具) 可不能在載入時擷取可用記憶體,然後就算了。而是必須定期地採擷最新的記憶體樣本。

聽起來挺複雜的,但是我們一次學習一項技巧,就可以將它簡化。先從討論 <SPAN> 標記開始,這是在小工具本身主體中顯示資訊一種簡單又容易的方法。

下面就是修改 HTML 檔之後的版本:在這個新的小工具當中,你還是要按按鈕,才能呼叫 RunSub 副程式,但是這次作業系統名稱不是回應在訊息方塊中,而是寫入小工具本身:


<html>

<head>
    <title>My First Gadget</title>
    <style>
        body{width:120;height:160}
    </style>
</head>

<script language="VBScript">

    Sub RunSub
        strComputer = "."

        Set objLocator = CreateObject("WbemScripting.SwbemLocator")
        Set objWMIService = objLocator.ConnectServer(strComputer, "root\cimv2")

        Set colItems = objWMIService.ExecQuery("Select * From Win32_OperatingSystem")

        For Each objItem in colItems
            DataArea.InnerHTML = objItem.Caption
        Next
    End Sub

</script>

<body>
    <input type="button" value="Run" name="run_button" onClick="RunSub"><br>
    <span id="DataArea"></span>
</body>

</html>


在這個小工具上按一下按鈕以後,傳回的資訊就會顯示在小工具本身之中:

Microsoft Gadget


不賴吧?

還有外加紅利:裝點小工具的背景

我們在本系列將來的篇章裡,會更深入地談如何建立外觀華麗的小工具。現在,我們想要提一些簡單的小技巧,讓你用來稍微裝飾一下小工具。例如,假設你有個圖形,你覺得用來做小工具的背景會很好看。這時候,你只需要設定 HTML 檔中 <BODY> 標記的 background 屬性就行了。這行程式碼會讓你的小工具使用 Background.jpg 檔做為小工具的背景:


<body background = "background.jpg">


只要確定該 Background.jpg 是儲存在你的 Gadget 資料夾就可以了。

另外你也可以新增 bgcolor 參數至 <BODY> 標記,用不同的背景顏色來建立小工具。想建立鮮紅色背景的小工具想瘋了嗎?現在可是易如反掌!


<body bgcolor = "red">


最後,你可以使用其中一個 Microsoft 多媒體 Web 濾鏡,讓小工具有個漸層色彩的背景。在這個小工具之中,我們用兩種方式修改了 <BODY> 樣式:

  • 我們將字型設定為白色,8-point Arial。

  • 我們加上漸層濾鏡。

修改後的小工具程式碼外觀如下:


<html>

<head>
    <title>My Gadget</title>
    <style>
        body{width:120;height:160;font:8 pt Arial;color:white;
        filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=1, StartColorStr="#000000",
            EndColorStr="#0000FF")}
    </style>
</head>

<script language="VBScript">

    Sub RunSub
        strComputer = "."
        Set objLocator = CreateObject("WbemScripting.SwbemLocator")
        Set objWMIService = objLocator.ConnectServer(".", "root\cimv2")
        Set colItems = objWMIService.ExecQuery("Select * From Win32_OperatingSystem")
        For Each objItem in colItems
            DataArea.InnerHTML = objItem.Caption
        Next
    End Sub

</script>

<body>
    <input type="button" value="Run" name="run_button" onClick="RunSub"><P>
    <span id="DataArea"></span>
</body>

</html>


小工具本身的外觀如下:

Microsoft Gadget


這談不上什麼大作,但是總比有個素白方塊啪嗒掉在資訊看板裡要好得多。

附註:如需有關使用漸層濾鏡的詳細資訊,請參閱 HTA 開發人員中心 (英文)。


建立「自動執行」的小工具

讓小工具在小工具主體中顯示資訊 (而不是在訊息方塊中顯示) 算是向前更邁進一步了,而且也更能表現出小工具的精神。但是我們還是必須按一下按鈕,才能取得資訊。一定還有方法,可以自動收集該項資訊,並在載入小工具時立刻顯示。

絕對有。還有別再叫我們靈犬雪莉了。

下面這個小工具會自動擷取並顯示所安裝作業系統的名稱,而不需要按任何按鈕:


<html>

<head>
    <title>My First Gadget</title>
    <style>
        body{width:120;height:160}
    </style>
</head>

<script language="VBScript">

    Sub Window_OnLoad
        RunSub
    End Sub

    Sub RunSub
        strComputer = "."

        Set objLocator = CreateObject("WbemScripting.SwbemLocator")
        Set objWMIService = objLocator.ConnectServer(strComputer, "root\cimv2")

        Set colItems = objWMIService.ExecQuery("Select * From Win32_OperatingSystem")

        For Each objItem in colItems
            DataArea.InnerHTML = objItem.Caption
        Next
    End Sub

</script>

<body>
    <span id="DataArea"></span>
</body>

</html>


你可以看到,外觀看起來跟先前的小工具很類似。兩段指令碼只有兩個不同之處:

  • 我們把按鈕從小工具之中移除。也就是說,不再需要按任何東西 (就此而言,根本沒有任何按鈕可按)。

  • 我們加了一段 Window_OnLoad 副程式。

你們有很多人都知道,Window_Onload 副程式 (如果包含在網頁中) 的設計是只要載入或重新整理網頁,就會隨時執行。這個副程式的運作方式當包含在小工具中時也完全相同。只要載入小工具,它就會自動執行。我們就是這麼建立自動執行的小工具:我們只是建立副程式 Window_OnLoad,然後將要在載入時執行的程式碼放入副程式中。

在這個特定的小工具中,我們的 Window_OnLoad 副程式如下所示:


Sub Window_OnLoad
    RunSub
End Sub


你可以看到,我們只不過在這個副程式中呼叫第二個副程式:RunSub 而已。在此也應該指明,我們不必另外將 WMI 程式碼放在不同的副程式中,我們可以將 WMI 指令碼放入 Window_OnLoad 副程式中,然後直接在啟動時執行該程式碼。那,我們幹嘛要多此一舉,另外建立第二個副程式呢?其實很簡單:它使我們順利地轉換到下一個小工具之中。

你要是想知道,我們「無按鈕」的小工具就如下所示:

Microsoft Gadget

建立「自動重新整理」的小工具

毫無疑問地,小工具大部份會因為做為監視裝置而佔有一席之地,盡責地追蹤記錄任何一切狀況,從可用的硬碟空間到網路連線功能到可用的記憶體。小工具非常適合執行這類工作:它們既小又不礙眼,同時卻還是可以顯示視覺提示,提供一目了然的資訊。同樣重要的是,小工具可以在發生特定情況時,以程式化方式採取行動。將小規模、圖形功能與自訂指令碼相結合,你可以建立極其有用的工具,來監視網路的健康和順暢狀況。

當然,執行這些工作的能力完全依小工具能夠不斷更新資訊的能力而定。有一件事很重要,小工具在啟動時可以 Ping 伺服器,並確認伺服器的可用性。但是,將小工具做為監視工具,若只能在啟動時 Ping 伺服器,那也沒什麼大用。小工具必須定期自己重新整理:它需要在定期間隔,擷取最新資訊。換句話說,必須如下執行:


<html>

<head>
    <title>My Gadget</title>
    <style>
        body{width:120;height:40"}
    </style>
</head>

<script language="VBScript">

    Sub Window_Onload
        GetMemory
        iTimerID = window.SetInterval("GetMemory", 10000)
    End Sub

    Sub GetMemory
        Set objLocator = CreateObject("WbemScripting.SwbemLocator")
        Set objWMIService = objLocator.ConnectServer(".", "root\cimv2")
        Set colItems = objWMIService.ExecQuery("Select * From Win32_OperatingSystem")
        For Each objItem in colItems
            DataArea.InnerHTML = objItem.FreePhysicalMemory
        Next
    End Sub

</script>

<body>
    <span id="DataArea"></span>
</body>

</html>


在討論這段指令碼的運作方式之前,我們應該提醒各位,這段特定的指令碼並不會顯示安裝在電腦上的作業系統名稱,而是顯示電腦上的可用記憶體量。我們為什麼忽然丟下作業系統小工具,轉而採取可用記憶體小工具呢?那是因為我們假定你不需要不斷監視已安裝作業系統的名稱,我們拍拍胸膛說:作業系統名稱的改變絕對比不上可用記憶體的頻繁。我們認為監視可用記憶體可能會比監視已安裝作業系統的名稱更加實際可行。

順帶一提,實際判斷目前可用記憶體量的副程式 (名為 GetMemory 的副程式) 如下所示:


Sub GetMemory
    Set objLocator = CreateObject("WbemScripting.SwbemLocator")
    Set objWMIService = objLocator.ConnectServer(".", "root\cimv2")
    Set colItems = objWMIService.ExecQuery("Select * From Win32_OperatingSystem")
    For Each objItem in colItems
        DataArea.InnerHTML = objItem.FreePhysicalMemory
    Next
End Sub


不過,這裡引發我們興趣的不是 GetMemory 副程式而是 Window_OnLoad 副程式:


Sub Window_Onload
    GetMemory
    iTimerID = window.SetInterval("GetMemory", 10000)
End Sub


您可以看到,在這個副程式中我們做了兩件事。第一,我們呼叫 GetMemory 副程式,這樣可以確保在載入小工具時,立即在小工具之中顯示可用記憶體。我們做的第二件事更饒趣味。


iTimerID = window.SetInterval("GetMemory", 10000)


有了這行程式碼,我們使用 SetInterval 方法來建立計時器。這個計時器的作用是促使我們的小工具每隔 10 秒 (10,000 毫秒) 呼叫 GetMemory 副程式。這是我們促使小工具自動對本身進行重新整理的方式。小工具會每隔 10 秒呼叫 GetMemory 副程式,也就是說,每隔 10 秒 小工具會使用 WMI,取得目前可用記憶體量,然後將該資料顯示在小工具主體中。如果 10 秒要測量太長,可將參數 10000 改為較小的數字,例如,設定參數為 5000 會導致小工具每隔 5 秒 (5000 毫秒) 更新本身的資訊。同樣地,如果習慣在測量時有更長間隔,可將 10000 變更為較大數目。

下面是新小工具執行中的情況:

Microsoft Gadget


我們從來沒說它算是傑作,但是現在瞭解建立小工具背後的基本原理之後 (尤其是對系統管理員有意義的小工具),才要開始建立大作,我們很快就會談到如何將圖形納入小工具之中,此外,我們也會探討小工具物件模型,以及能用模型來執行的一些非常酷的事情。

下一篇精彩預告

為了讓你更加瞭解小工具的功用,下面有稍微 (要特別強調「稍微」) 複雜一點的小工具,可以執行兩項工作:按下 [資訊] 按鈕時,它會監視可用記憶體,同時 (在網頁中) 顯示更詳細的系統資訊。不用說也知道,這根本都還沒碰到小工具真正的功用,但確實能夠讓你更加瞭解可以包含在單單一個小工具裡頭的功能範圍。

你得靠自己摸索到底為什麼特別用這個小工具 (我們這個月的空間已經用光了),不過程式碼如下:


<html>

<head>
    <title>My Gadget</title>
    <style>
        body{width:120;height:80}
    </style>
</head>

<script language="VBScript">

    Sub Window_Onload
        GetMemory
        iTimerID = window.SetInterval("GetMemory", 10000)
    End Sub

    Sub GetMemory
        Set objLocator = CreateObject("WbemScripting.SwbemLocator")
        Set objWMIService = objLocator.ConnectServer(".", "root\cimv2")
        Set colItems = objWMIService.ExecQuery("Select * From Win32_OperatingSystem")
        For Each objItem in colItems
            DataArea.InnerHTML = objItem.FreePhysicalMemory
        Next
    End Sub

    Sub RunSub

        Set objLocator = CreateObject("WbemScripting.SwbemLocator")
        Set objWMIService = objLocator.ConnectServer(".", "root\cimv2")

        Set colItems = objWMIService.ExecQuery("Select * From Win32_ComputerSystem")
        For Each objItem in colItems
            strHTML = "Computer Name: " & objItem.Name & "<br>"
            strHTML = strHTML & "User Name: " & objItem.UserName & "<br><br>"
        Next

        Set colItems = objWMIService.ExecQuery("Select * From Win32_OperatingSystem")
        For Each objItem in colItems
            strHTML = strHTML & "Operating System: " & objItem.Caption & "<br>"
            strHTML = strHTML & "Service Pack: " & objItem.ServicePackMajorVersion & "<br><br>"
        Next

        Set colItems = objWMIService.ExecQuery("Select * From Win32_Processor")
        For Each objItem in colItems
            strHTML = strHTML & "Processor: " & objItem.Caption & "<br><br>"
        Next

        Set colItems = objWMIService.ExecQuery _
            ("Select * From Win32_NetworkAdapterConfiguration Where IPEnabled = True")
        For Each objItem in colItems
            strHTML = strHTML & objItem.Caption & "<br>"
            For Each strAddress in objItem.IPAddress
                strHTML = strHTML & "IP Address: " & strAddress & "<br>"
            Next
        Next

        Set objIE = CreateObject("InternetExplorer.Application")
        objIE.Navigate("about:blank")
        objIE.Toolbar = 0
        objIE.StatusBar = 0
        Set objDoc = objIE.Document.Body
        objDoc.InnerHTML = strHTML
        objIE.Visible = True
    End Sub

</script>

<body>
    <span id="DataArea"></span><p>
    <input type="button" value="Information" name="run_button" onClick="RunSub">
</body>

</html>


相关链接

顯示: