嗨,Scripting Guy!

Hey,Scripting Guy!

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

今天的問題:我要如何從指令碼將資料傳送到其他指令碼?


我要如何從指令碼將資料傳送到其他指令碼?

嗨,Scripting Guy!不久之前您才為我們示範如何使用 InputBox 函式來提示使用者輸入值,然後我們就可以在指令碼中使用該值。我想要知道的是,是否有任何方法可以讓我取得該值,並將該值用於「其他」指令碼?

-- JW

JW,您好。我們必須猜測一下,不過顯然在您需要的許多指令碼功能中,有一項是必須對使用者提示以取得一些資料。然後您想啟動第二個指令碼,並讓第二個指令碼能夠存取使用者在第一個指令碼中輸入的資料。而且,您當然也想知道是否甚至有可能辦到這點。

答案是 (很懸疑緊張吧?):多少可以。假設您啟動指令碼 A,然後輸入一個值。現在您是否可以獨立地啟動指令碼 B,然後讓指令碼 B 探入指令碼 A 並擷取該值?不行。這似乎更像是魔法而非指令碼。不過,您可以這樣做:啟動指令碼 A 並讓使用者輸入資料。然後使用指令碼 A 來啟動指令碼 B。您這麼做時,就能將資料傳遞到指令碼 B。如此一來,指令碼 B 就能完整存取使用者輸入的所有資訊。

為了更清楚地解釋這點,讓我們觀察一個非常簡單的範例。我們需要 2 個指令碼:指令碼 A 和指令碼 B。在啟動指令碼 A 時,指令碼將提示使用者輸入一個號碼。然後指令碼 A 便會啟動指令碼 B。在啟動指令碼 B 時,指令碼 A 也會傳遞使用者所輸入的數字。然後,指令碼 B 就會取用該數字,決定該數字的平方根,並且報告答案。

注意:在此情況下,是否能讓一個指令碼接受使用者的輸入「並」計算出平方根,好讓工作更容易進行?可以。不過請記得,這個指令碼的設計,是要用來示範從一個指令碼傳遞資料到其他指令碼的方式,而不是做為在實際工作時所使用的指令碼。

以下是指令碼 A。請注意我們一開始就建立 WSH Shell 物件的例項,這個物件會在稍後用來啟動指令碼 B (我們將指令碼 B 命名為 output.vbs,指令碼 A 則命名為 input.vbs)。然後我們使用 InputBox 函式要求使用者輸入數字:

Set objShell = CreateObject("Wscript.Shell")
intValue = InputBox("Please enter a number:")
strCommandLine = "output.vbs " & intValue
objShell.Run(strCommandLine)

請注意我們在使用者輸入數字之後的動作 (我們假設使用者輸入數字 2)。我們使用以下這行程式碼:

strCommandLine = "output.vbs " & intValue

此程式碼會建構命令以啟動指令碼 B。這裡假設您要啟動指令碼 B,然後對它傳遞數字 2 做為命令列引數。如果要這樣做,您必須從命令提示字元輸入以下命令:

output.vbs 2

我們的做法是建立包含這兩個項目的字串:我們要啟動的指令碼名稱 (output.vbs),以及我們要傳遞的命令列引數 (2)。當然,我們不知道引數其實是 2,我們只是傳遞使用者所輸入的任何數值。這就是我們為何使用變數 intValue 的原因。並請注意,output.vbs (加上一個空格) 被包含在雙引號「內」,intValue 則是位於這兩個雙引號「外」。為何不將 intValue 放在雙引號內?理由很簡單。因為我們建構的這道命令,它不會傳遞數字 2 (或是使用者輸入的其他任何數字),而是傳遞字串值 intValue:

output.vbs intValue

這可不是我們要的。

在建構命令列以後,我們使用 Run 方法來啟動指令碼 B,將使用者輸入的值傳遞為命令列引數。

那麼指令碼 B 看來像什麼樣子?好的,應該會很像這個樣子:

intValue = Wscript.Arguments.Item(0)
intSquareRoot = Sqr(intValue)
Msgbox "The square root of " & intValue & _
    " is " & intSquareRoot & "."

如您所見,我們將第一個 (在此情況下,也是唯一的) 命令列引數指派給變數 intValue。然後,我們使用 Sqr 函式來決定該值的平方根。最後,我們顯示答案。在此情況下,我們使用 VBScript 的 Msgbox 函式 (而不是 Wscript.Echo) 確保答案會出現在訊息方塊中。如果我們使用 Wscript.Echo,而且 Cscript 是您的預設指令碼裝載,就會短暫開啟一個命令視窗,將答案顯示在畫面中,然後視窗就會消失,讓您根本沒有機會確實「看到」答案。又一次,這不是我們要的。無論指令碼裝載為何,Msgbox 函式「一定」都會在訊息方塊中顯示資料,所以我們選擇使用 Msgbox。

以下是另一個非常簡單的範例,不過它可以輕易擴充,將 2、3、4 或任何命令列引數的數字,從指令碼 A 傳送到指令碼 B。儘管在理論上,如果嘗試傳遞過多的資料,就會遭受命令列字串長度的限制,不過這樣做是絕對有效的。在此情況下,您的最佳選擇是讓指令碼 A 將資料儲存為文字檔,然後讓指令碼 B 從相同的檔案讀取資料。

您也必須謹慎使用會傳送命令列引數 (內含空格) 的指令碼。例如:假設您要將 Ken Myer 名稱傳送給指令碼 B。以下命令就不會產生作用。它會傳送 2 個引數 (KenMyer),而不是單一的引數 Ken Myer:

output.vbs Ken Myer

如下所示,因為 Ken 和 Myer 兩個字之間的空格 (WSH 用空格決定一個引數的結束和下個引數的開始),您必須將 Ken Myer 置於雙引號之中:

output.vbs "Ken Myer"

這也就表示,您所建構的命令列字串也必須含有雙引號。以下是一種可行方法,如需詳細資訊,請參閱這篇過去的嗨,Scripting Guy!專欄 (英文):

strCommandLine = "output.vbs " & chr(34) & strValue & chr(34)

在此範例中,chr(34) 的每個例項都插入一個雙引號。因此我們最後得到 output.vbs"Ken Myer",也就是:

output.vbs "Ken Myer"

如需詳細資訊

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

 

回到頁首 回到頁首