嗨,Scripting Guy!

Hey,Scripting Guy!

歡迎使用全新的 TechNet 專欄,Microsoft Scripting Guy 會在此為您解答有關系統管理指令碼的常見問題。您有關於系統管理指令碼方面的問題嗎?請將電子郵件傳送到 scripter@microsoft.com。我們無法保證能夠逐一回答每個問題,不過我們會盡力而為。

今天的問題:如何使用指令碼從表單進行選取?


如何使用指令碼從表單進行選取?

嗨,Scripting Guy!我想要撰寫具有四個選項按鈕的表單,其中每個按鈕都代表不同的電腦。選擇選項按鈕後再按一下其他按鈕,就會針對選取的電腦執行指令碼。我該如何做到這點呢?

-- CW

CW,您好。如果我們的討論限制在 VBScript 和 Windows Script Host,那麼答案就很簡單:沒有辦法。除了顯示訊息方塊之外,VBScript 或 WSH 都沒有建立圖形化使用者介面的功能,從指令碼內是沒有辦法使用選項按鈕、清單方塊、下拉式清單和其他圖形化元素的。

但是,您一定已經遇過這種情況。沒錯:先告訴您這件事沒辦法達成,然後再告訴您完成它的方法 (哈,每個人總是要用些花招,不是嗎)。而您的想法很正確:雖然不能只用 VBScript 進行這項作業,但是您絕對可以使用 HTA (HTML 應用程式) 做到它。

我們現在不會針對 HTA 多做說明,如果您有興趣,可以參閱一年前有關這個主題的「網路廣播」。當中充分說明 HTA 可以讓我們將 Internet Explorer 與指令碼結合,進而提供指令碼一個圖形化使用者介面。雖然還有其他方法可以將圖形化使用者介面併入指令碼中,但對於剛踏入 GUI 開發作業的使用者而言,這可能是最簡單的一種方法。

就先從提供您 HTA 程式碼開始吧,接著再說明它的運作方式。這個範例 HTA 會顯示四個選項按鈕,每個都代表不同的電腦。您可以選取電腦再按一下 [Run Script] 按鈕;當您這麼做時,執行的副程式將會讀取選取內容、連線到選擇的電腦,然後回報該電腦所安裝的作業系統。很棒吧?若要查看這段指令碼的運作方式,請複製程式碼並將它貼入「記事本」,再使用 .hta 副檔名儲存檔案 (例如 os_name.hta)。請勿使用 .vbs 副檔名,這是無法作用的。副檔名一定要是 .hta。

<SCRIPT LANGUAGE="VBScript">
Sub RunScript
    If ComputerOption(0).Checked Then
        strComputer = ComputerOption(0).Value
    End If
    If ComputerOption(1).Checked Then
        strComputer = ComputerOption(1).Value
    End If
    If ComputerOption(2).Checked Then
        strComputer = ComputerOption(2).Value
    End If
    If ComputerOption(3).Checked Then
        strComputer = ComputerOption(3).Value
    End If
    If strComputer = "" Then
        Exit Sub
    End If
    Set objWMIService = GetObject _
        ("winmgmts:\\" & strComputer & "\root\cimv2")
    Set colItems = objWMIService.ExecQuery _
        ("Select * From Win32_OperatingSystem")
    For Each objItem in ColItems
        Msgbox objItem.Caption
    Next
End Sub
Sub CancelScript
   Self.Close()
End Sub
</SCRIPT>
<BODY>
<input type="radio" name="ComputerOption" value="atl-ws-01">atl-ws-01<BR>
<input type="radio" name="ComputerOption" value="atl-ws-02">atl-ws-02<BR>
<input type="radio" name="ComputerOption" value="atl-ws-03">atl-ws-03<BR>
<input type="radio" name="ComputerOption" value="atl-ws-04">atl-ws-04<P>
<input id=runbutton class="button" type="button" value="Run Script" name="ok_button" 
onClick="RunScript">
&nbsp;&nbsp;&nbsp;
<input id=runbutton class="button" type="button" value="Cancel" name="cancel_button" 
onClick="CancelScript">
</BODY>

那麼這裡有些什麼呢?我們可以將這段程式碼分為四個部份:其中兩個部份會使用 HTML 標記顯示選項按鈕以及 [Run Script] 和 [Cancel] 按鈕,而另外兩個部份則會依據您按下的是 [Run Script] 或者是 [Cancel] 而執行副程式。讓我們進一步檢視這些部份。

舉例來說,這裡是顯示四個選項按鈕的 HTML 程式碼 (如果您瞭解 HTML,就知道這裡並沒有什麼特殊的地方,不過是標準的 HTML 程式碼)。請注意所有的按鈕都使用相同的名稱 (ComputerOption),這是確保每次只能選取一個按鈕的必要方法。也請注意每個按鈕值都設定成各個電腦的名稱:

<BODY>
<input type="radio" name="ComputerOption" value="atl-ws-01">atl-ws-01<BR>
<input type="radio" name="ComputerOption" value="atl-ws-02">atl-ws-02<BR>
<input type="radio" name="ComputerOption" value="atl-ws-03">atl-ws-03<BR>
<input type="radio" name="ComputerOption" value="atl-ws-04">atl-ws-04<P>

而以下是顯示 [Run Script] 和 [Cancel] 按鈕的程式碼。這裡的重點是 onClick 參數,它用來指示按下按鈕時所要執行的副程式。如您所見,按一下第一個按鈕會執行副程式 RunScript,而按一下第二個按鈕則會執行副程式 CancelScript:

<input id=runbutton class="button" type="button" value="Run Script" name="ok_button" 
onClick="RunScript">
&nbsp;&nbsp;&nbsp;
<input id=runbutton class="button" type="button" value="Cancel" name="cancel_button" 
onClick="CancelScript">
</BODY>

順便一提,CancelScript 副程式只是關閉 HTA。您可以看出這裡並沒有特別複雜的程序:

Sub CancelScript
   Self.Close()
End Sub

現在,終於來到精采的部份了。當您選取選項按鈕,然後按下 [Run Script] 時:HTA 怎麼知道您是選取哪個按鈕,又怎麼知道要在哪個電腦上執行指令碼呢?關於這部份,天知道要執行的指令碼在哪?放輕鬆,所有的答案都在 RunScript 副程式中:

Sub RunScript
    If ComputerOption(0).Checked Then
        strComputer = ComputerOption(0).Value
    End If
    If ComputerOption(1).Checked Then
        strComputer = ComputerOption(1).Value
    End If
    If ComputerOption(2).Checked Then
        strComputer = ComputerOption(2).Value
    End If
    If ComputerOption(3).Checked Then
        strComputer = ComputerOption(3).Value
    End If
    If strComputer = "" Then
        Exit Sub
    End If
    Set objWMIService = GetObject _
        ("winmgmts:\\" & strComputer & "\root\cimv2")
    Set colItems = objWMIService.ExecQuery _
        ("Select * From Win32_OperatingSystem")
    For Each objItem in ColItems
        Msgbox objItem.Caption
    Next
End Sub

副程式的前半部份會判斷所選取的按鈕是哪一個。選項按鈕會以陣列的方式儲存 (至少對具有相同名稱的按鈕而言),在陣列中的第一個按鈕是項目 0,在陣列中的第二個按鈕是項目 1,依此類推。這裡是藉由查看每個按鈕的 Checked 屬性,以判斷選取的是哪一個按鈕。例如,這行程式碼會查看按鈕 0 (陣列的第一個按鈕) 的 Checked 屬性是否為 True,如果是的話,代表這就是選取的按鈕:

If ComputerOption(0).Checked Then

而當 Checked 是 True 又會怎樣?接著會將選項按鈕的值 (要記得,按鈕值正巧就是電腦的名稱) 指派給變數 strComputer:

strComputer = ComputerOption(0).Value

而當 Checked 是 False 又會怎樣?沒什麼大不了,畢竟會檢查每個選項按鈕的值嘛。遲早會找到選取的按鈕的 (而且只能有一個)。如果最後發現沒有選取任何按鈕,那就直接結束副程式。也就是這行程式碼的作用:

If strComputer = "" Then
    Exit Sub
End If

如果選取了按鈕,strComputer 就會等於要連線的電腦名稱。而這即是這個副程式後半部的作用:這個標準的 WMI 指令碼會連線至指定的電腦,並傳回所安裝的作業系統名稱。

哇!相信您一定很高興「這樣」就完成了,對不對?或者,至少在實際完成時您會很高興吧。但還有另外一點我們必須說明:這裡顯示的範例 HTA 是擷取電腦上安裝的作業系統名稱,然後將名稱顯示於訊息方塊中;這部份還好,但好比說,萬一您想顯示的是安裝在電腦上所有服務的清單呢?如果是這樣,您會發現自己不斷地在回覆訊息方塊,這應該不是您所樂見的使用者體驗。

那麼我們可以修正這個問題嗎?當然。我們不打算花太多時間在這個部份,但有小地方需要注意。首先,必須在 HTA 中加入 SPAN 區域,這只是螢幕上可以寫入資訊的可辨識區域。在所有按鈕下,使用類似下方的程式碼放置 SPAN (ID 為 DataArea):

<P>
<span id=DataArea></span>

第二,我們需要收集資料並全部儲存在一個變數中,而非在訊息方塊中顯示所有資料。這行程式碼會將變數 strText 的值設為目前 strText 中所有的資料,加上 Caption 屬性的值,再加上 <BR> 標記 (這個 HTML 標記等同於在鍵盤按 ENTER 鍵):

strText = strText & objItem.Caption & "<BR>"

最後,需要將 SPAN 的 InnerHTML 屬性設定為變數 strText 的值:

DataArea.InnerHTML = strText

您都看懂了嗎?再次,不用多做解釋,這裡是修訂過的 HTA,它會收集電腦上安裝的所有服務名稱,然後將這些名稱寫入 HTA 本身:

<SCRIPT LANGUAGE="VBScript">
Sub RunScript
    If ComputerOption(0).Checked Then
        strComputer = ComputerOption(0).Value
    End If
    If ComputerOption(1).Checked Then
        strComputer = ComputerOption(1).Value
    End If
    If ComputerOption(2).Checked Then
        strComputer = ComputerOption(2).Value
    End If
    If ComputerOption(3).Checked Then
        strComputer = ComputerOption(3).Value
    End If
    If strComputer = "" Then
        Exit Sub
    End If
    Set objWMIService = GetObject _
        ("winmgmts:\\" & strComputer & "\root\cimv2")
    Set colItems = objWMIService.ExecQuery _
        ("Select * From Win32_Service")
    For Each objItem in ColItems
        strText = strText & objItem.Name & "<BR>"
    Next
    DataArea.InnerHTML = strText
End Sub
Sub CancelScript
   Self.Close()
End Sub
</SCRIPT>
<BODY>
<input type="radio" name="ComputerOption" value="atl-ws-01">atl-ws-01<BR>
<input type="radio" name="ComputerOption" value="atl-ws-02">atl-ws-02<BR>
<input type="radio" name="ComputerOption" value="atl-ws-03">atl-ws-03<BR>
<input type="radio" name="ComputerOption" value="atl-ws-04">atl-ws-04<P>
<input id=runbutton class="button" type="button" value="Run Script" name="ok_button" 
onClick="RunScript">
&nbsp;&nbsp;&nbsp;
<input id=runbutton class="button" type="button" value="Cancel" name="cancel_button" 
onClick="CancelScript">
<P>
<span id=DataArea></span>
</BODY>

如需詳細資訊

查看嗨,Scripting Guy!- 過往文件

 

回到頁首 回到頁首