20131229

const 常數

Const Statement (VBScript)

1 out of 1 rated this helpful Rate this topic
Declares constants for use in place of literal values.
[Public | Private] Const constname = expression
Public
Optional. Keyword used at script level to declare constants that are available to all procedures in all scripts. Not allowed in procedures.
Private
Optional. Keyword used at script level to declare constants that are available only within the script where the declaration is made. Not allowed in procedures.
constname
Required. Name of the constant; follows standard variable naming conventions.
expression
Required. Literal or other constant, or any combination that includes all arithmetic or logical operators except Is.

Constants are public by default. Within procedures, constants are always private; their visibility can't be changed. Within a script, the default visibility of a script-level constant can be changed using the Private keyword.
To combine several constant declarations on the same line, separate each constant assignment with a comma. When constant declarations are combined in this way, the Public or Privatekeyword, if used, applies to all of them.
You can't use variables, user-defined functions, or intrinsic VBScript functions (such as Chr) in constant declarations. By definition, they can't be constants. You also can't create a constant from any expression that involves an operator, that is, only simple constants are allowed. Constants declared in a Sub or Function procedure are local to that procedure. A constant declared outside a procedure is defined throughout the script in which it is declared. You can use constants anywhere you can use an expression. The following code illustrates the use of theConst statement:
                      Const MyVar = 459   ' Constants are Public by default.
Private Const MyString = "HELP"   ' Declare Private constant.
Const MyStr = "Hello", MyNumber = 3.4567   ' Declare multiple constants on same line.

連Oracle資料庫

the error message "Class not defined ADODB"
Set Obj_DBConn = New ADODB.Connection
Set cat = New ADOX.Catalog



Obj_DBConn.ConnectionString ="Driver={Microsoft ODBC for Oracle}; " & _
                             "CONNECTSTRING=(DESCRIPTION=" & _
                             "(ADDRESS=(PROTOCOL=TCP)" & _
                             "(HOST=##test##)(PORT=##test##))" & _
                             "(CONNECT_DATA=(SERVICE_NAME=##test##))); " & _
                             "uid=test;pwd=test;"


Obj_DBConn.Open Database_Path


Const ForReading = 1, ForWriting = 2, ForAppending = 8
Dim fso, f
Set fso = CreateObject("Scripting.FileSystemObject")




Set f = Nothing

Set f = fso.OpenTextFile("C:\Documents and Settings\test.txt", ForReading, True)

For i = 1 To 10000

v_Line_String = f.ReadLine


v_Output_Each_part = Split(v_Line_String,";",-1,1)

v_Col_A = v_Output_Each_part(0)
v_Col_B = v_Output_Each_part(1)
v_Col_C = v_Output_Each_part(2)



Obj_DBConn.Execute "INSERT INTO  test_me (ID_Q, NAME, ROLLNO) VALUES ('"       & v_Output_Each_part(0) & "','" & v_Output_Each_part(1) & "','" & v_Output_Each_part(2) & "')"



Next

20131117

VBScript字串處理



字串型態表示包含一個可變長度的字串,其長度最長可以到將近 20 億個字元。

操作

串接字串& 運算子

字串相連結。例如 Y=A&B。將 A 值與 B 值相連結後取代原來 Y 值。

索引操作

Left(string, length)
傳回 string 字串最左邊 length 個字元。

Right(string, length)
傳回 string 字串最右邊的 length 個字元。

Mid(string, start [, length])
傳回 string 字串中由 start 開始,長度 length 的子字串。

尋找字串

InStr([start,] string1, string2 [,compare])

傳回子字串 string2 在字串 string1 中的啟始位置,若找不到該子字串,則傳回 0。

InStrRev(string1, string2 [,start [,compare]])

傳回子字串 string2 在字串 string1 中從尾端算起的位置,若找不到該子字串,則傳回 0。

利用RegEx物件來尋找符合模式之字串位置

CStr(expression) 傳回 expression 的字串值。

Filter(InputString, Value [, Include [, Compare]]) 
傳回 Value 在 InputString 一維陣列搜尋的結果。

Len(string | varname)
傳回 string 字串或 varname 字串變數的長度。

StrReverse(string) 傳回一個 string 字串的反向字串。

LTrim(string) 將 string 字串前的空白去除。

RTrim(string) 去除 string 字串尾部的空白並傳回。

Trim(string) 去除 string 字串頭尾的空白並傳回。

LCase(string) 將 string 轉換為英文小寫字母。

Replace(expression,find,replacewith [,start [,count [,compare]]]) 在 expression 字串中找到 find 子字串後以 replacewith 字串取代後傳回。

Split(expression [, delimiter [, count [, compare]]]) 將以 delimiter 為隔開符號的 expression 字串剖開後存入一個一維陣列後傳回。

Join(list [, delimiter])
傳回一維陣列 list 中每一個元素字串的連結字串,若省略 delimiter 則以空白隔開。

StrComp(string1, string2 [, compare])
將 string1、string2 二字串相比較,結果以整數表示,若 string1 較 小則傳回 -1,相等則傳回 0,較大則傳回 1。若其中有一個為 Null 則 傳回 Null。

String(number, character) 傳回一個 number 個 character 字元的字串。

Space(number) 傳回一個長度為 number 的空白字串。




20131114

更改預設的指令碼為 cscript

cscript.exe 與 wscript.exe 不同於 cscript 主要用於命令列,wscript 

I was able to solve it by using the following steps:
  1. selecting the VBScript file that I want to open,
  2. right click to select default program for this,
  3. browse to C:/windows/windows32/wscript.exe, and select this.

命令提示字元基本輸出入

顯示Console的輸入與輸出
 
要在 命令提示字元 視窗中顯示Console的輸入與輸出,您可以使用WSH 2中的StdIn和StdOut串流屬性。要使用這些串流屬性,您必須在CScript.exe中執行Script。(WScript.exe則會導致執行時期的錯誤,因為Windows應用程式並不支援輸入與輸出串流。)
下面的範例使用WSH 2的方法從命令列讀取使用者的輸入並顯示輸入的字串。這個Script必須在CScript.exe中被執行。因為不保證使用將以正確的主機來啟動Script,所以Script本身會強制CScript.exe的執行。
If (Not IsCScript( )) Then
    Set WshShell = WScript.CreateObject("WScript.Shell")
    WshShell.Run "CScript.exe " & WScript.ScriptFullName 
    WScript.Quit            ' 結束Script
End If
如果使用者自訂的函數IsCScript傳回False值,則Script將會執行Run方法來啟動此Script的第2個副本。這個副本會被以CScript.exe來執行。函數IsCScript使用下面的程式碼:
Function IsCScript( )
    ' 檢查CScript.exe是否為主機
    If (InStr(UCase(WScript.FullName), "CSCRIPT") <> 0) Then
        IsCScript = True
    Else
        IsCScript = False
    End If
End Function
這個函數會檢查主機是否傳回包含「CSCRIPT」的字串。這個字串會從WScript物件的FullName屬性中被傳回。
您可以使用下面的命令來撰寫輸出串流:
WScript.StdOut.WriteLine "請輸入:"
這個命令使用WScript物件的StdOut屬性並執行WriteLine方法。此方法會在 命令提示字元 視窗中顯示傳遞過來的參數,如圖14-4所示。

 
 圖14-4 使用者在 命令提示字元 中的輸入
要從Console輸入中讀取使用者的輸入,您可以使用WScript物件的StdIn屬性的ReadLine方法,範例如下:
tmp = WScript.StdIn.ReadLine
從這個方法傳回的使用者輸入會被指定給變數tmp。ReadLine會暫停Script直到新行字元被偵測到(也就是說,直到使用者按下 Enter 鍵為止)。完整的範例程式碼如程式14-7所示。
 程式14-7 StdIO.vbs
'************************************************
' 檔案:  StdIO.vbs (WSH 2 sample in VBScript) 
' 作者:  (c) G. Born
'
' 使用WSH 2的StdIn和StdOut屬性
'************************************************
Option Explicit
Dim tmp, WshShell
' 測試主機是否為CScript.exe
If (Not IsCScript( )) Then
    Set WshShell = WScript.CreateObject("WScript.Shell")
    WshShell.Run "CScript.exe " & WScript.ScriptFullName 
    WScript.Quit            ' 結束Script
End If

WScript.StdOut.WriteLine "請輸入:"
tmp = WScript.StdIn.ReadLine

WScript.StdOut.WriteLine "您輸入的是:" & tmp

WScript.StdOut.WriteLine "請按【Enter】鍵!"
tmp = WScript.StdIn.ReadLine ' 等待直到按鍵被按下了

Function IsCScript( )
    ' 檢查CScript.exe是否為主機
    If (InStr(UCase(WScript.FullName), "CSCRIPT") <> 0) Then
        IsCScript = True
    Else
        IsCScript = False
    End If
End Function
'*** 程式結束
寫入一行並讀取之
 
上面的範例會寫入字串到命令列中、強制換行,並讀取使用者的輸入。在大部分的情況下,您應該在同一行寫入字串並讀取使用者的輸入。您可以使用Write方法而非WriteLine方法來達到這個目的:
WScript.StdOut.Write("請輸入數字:")
上面的敘述會寫入文字到命令列中但是並不會移動游標到下一行。使用者接著可以在 命令提示字元 視窗的同一行輸入數字。這個使用者輸入可以被以Read方法或ReadLine方法來讀取。
您可以使用Read方法來讀取特定數目個字元。下面的命令會在使用者按下 Enter 鍵之後取得輸入的第1個字元:
tmp = WScript.StdIn.Read(1)
如果使用者輸入字串1234{Enter}(其中 {Enter} 代表 Enter 鍵),則Read(1) 便會傳回數值1。(當從資料檔中讀取固定長度的欄位時,Read方法尤其有用。)程式14-8顯示的是如何使用Write和Read來處理一行中使用者的輸入和訊息。
 程式14-8 StdIO1.vbs
'************************************************
' 檔案:  StdIO1.vbs (WSH 2 sample in VBScript) 
' 作者:  (c) G. Born
'
' 使用WSH 2的StdIn和Stdout屬性
'************************************************
Option Explicit
Dim tmp, WshShell
' 測試主機是否為CScript.exe
If (Not IsCScript( )) Then
    Set WshShell = WScript.CreateObject("WScript.Shell")
    WshShell.Run "CScript.exe " & WScript.ScriptFullName 
    WScript.Quit            ' 結束Script
End If

' 寫入不換行的字串
 WScript.StdOut.Write("請輸入3位數的數字並按下【Enter】鍵:")
' 使用Read方法來取得輸入的第1個字元
tmp = WScript.StdIn.Read(1)

' 顯示資料
WScript.StdOut.WriteLine("第1個字元是:" & tmp)

' 下一行
WScript.StdOut.Write("請輸入3位數的數字並按下【Enter】鍵:")

' 使用ReadLine來取得資料
tmp = WScript.StdIn.ReadLine( )

' 使用Echo方法來顯示輸入
WScript.Echo "您輸入的是:", tmp
WScript.Echo "請按下【Enter】鍵來結束Script!" 

WScript.Echo WScript.StdIn.Read(1)  ' 等待
Function IsCScript( )
    ' 檢查CScript.exe是否為主機
    If (InStr(UCase(WScript.FullName), "CSCRIPT") <> 0) Then
        IsCScript = True
    Else
        IsCScript = False
    End If
End Function
'*** 程式結束

14. 程式設計的技巧與秘訣
本章將提供許多處理Microsoft Windows Script Host(WSH)的有用技巧與秘訣,其中有些部分已經在前面的章節中介紹過了。他們被組織為一般的主題:執行時期的錯誤;長檔名、AT命令和系統呼叫;使用者對話盒與輸出;檔案處理;播放音樂;Windows Shell;以及呼叫DUN連線等。執行時期的錯誤
 

VBScript和JScript都提供行內(inline)的錯誤處理,也就是說您的Script可以從會導致Script結束的錯誤中攔截並取得。在本節中,將概述您在Script中使用明確的執行時期錯誤處理時所需要知道的知識。
在VBScript中處理執行時期的錯誤
 

您可以在VBScript中藉由使用在執行時期的錯誤發生之後會導致下一個敘述繼續被執行的On Error Resume Next敘述來實作明確的執行時期錯誤處理。這個敘述允許行內的執行時期錯誤處理。(只有語法錯誤還會被指令引擎報告出來。)
您可以使用Err物件來取得錯誤代碼。舉例來說,如果oWSH是一個指向WshShell物件的物件變數,那麼您可以在使用RegRead方法時檢查可能會被喚起的錯誤:
valx = oWSH.RegRead("....", "xxxx")
If Err <> 0 Then
.
.
.
如果在第1敘述執行時執行時期的錯誤發生,則Err物件的值便不會等於0。您可以使用Err.Number來取得錯誤代碼,以及使用Err.Description來取得錯誤訊息。在前面的許多章節中皆使用此技巧來處理執行時期的錯誤。
您可以使用On Error GoTo 0敘述來取消執行時期錯誤的處理。在這個敘述之後,將換由指令引擎來處理執行時期的錯誤。

注意
如同我所說過的,啟動行內之執行時期錯誤的處理將禁止所有不明確的錯誤訊息,所以您的Script便必須負起偵測與報告執行時期錯誤的責任。這個方法的危險之處在於某個難以發現的錯誤可能會被忘了偵測。即使Script包含Option Explicit敘述,打字錯誤的變數與函數或程序名稱也可能不會被報告為錯誤。相反地,敘述只會失敗,而指令引擎則會移到下一個敘述繼續執行。要避免這種風險,在此強烈建議您盡可能越快越好在啟動執行時期錯誤的處理之後便取消他(使用On Error GoTo 0)。

在JScript中處理執行時期的錯誤
 

JScript在第5版和更新版的指令引擎中支援執行時期錯誤的處理。您可以下面的方式來使用try {...} catch (e) {...} 敘述:
try
{
    var valx = WSH.RegRead("....", "xxxx");
}
catch (e)
{
    if (e != 0)
        WScript.Echo("在登錄存取時發生錯誤囉!");
}
您必須在敘述的前面設定try關鍵字。您可以將敘述或敘述區塊圍在大括號裡面。如果執行時期的錯誤發生,則catch (e) 敘述便會被呼叫。變數e會取得可以被下面的catch區塊中的敘述來處理的錯誤物件。(這些敘述也必須被以大括號給圍住。)
在VBScript中喚起執行時期的錯誤
 

您可藉由使用指令語言提供的方法來喚起您自己的執行時期錯誤。在VBScript中,您可以使用Err物件的Raise方法。下面的程式碼會喚起執行時期的錯誤並顯示其錯誤訊息:
On Error Resume Next
Err.Clear
Err.Raise   ' 喚起錯誤

MsgBox "錯誤代碼:" & Err.Number & vbCrLf & Err.Description, _
       vbOKOnly, "VBScript錯誤訊息"

On Error GoTo 0
這個程式碼會模擬溢位錯誤(代碼6)。您可以使用這個程式碼片段來撰寫詢問錯誤代碼並傳回錯誤訊息的VBScript程式。

說明
在隨書光碟的\WSHDevGuide\Chapter14資料夾中的VBScriptError.vbs會詢問錯誤號碼並顯示其錯誤訊息。所有的錯誤訊息在〈VBScript程式語言參考〉文件中也都有說明。但是由作業系統(或OLE或COM元件)所造成的錯誤則無說明。您可以使用正確的Windows API呼叫以便從內部表格中獲得這些錯誤訊息,但是這些技巧已經超出本書所討論的範疇。

路徑與日期
 

要存取外部檔案,您將需要那些檔案的路徑。在本節中,我們將測驗如何取得目前Script檔案的資料夾、預設的資料夾或磁碟機。此外也將說明使用日期差值的易犯錯誤。
取得Script的路徑
 

有些時候知道您Script的路徑是非常方便的─舉例來說,當您想要處理位於您Script資料夾中的檔案。使用Script的路徑當作開始位置比使用絕對路徑還不易犯錯,因為Script的路徑總是有效的(甚至在更名Script資料夾或將其搬移到另一部磁碟機之後)。WSH並沒有取得Script路徑的函數或方法,所以在VBScript中您可以使用WScript物件的ScriptFullName屬性來抽選出路徑,範例如下:
Function GetPath
    ' 取得Script檔案的路徑
    Dim path
    path = WScript.ScriptFullName  ' Script檔名
    GetPath = Left(path, InStrRev(path, "\"))
End Function
而在JScript中,您可以使用下面的函數來取得路徑:
function GetPath( )
{
    // 取得Script檔案的路徑
    var path = WScript.ScriptFullName;  // Script檔名
    path = path.substr(0, path.lastIndexOf("\\") + 1);
    return path;
}
這兩個函數都假設路徑是以反斜線字元結尾的。如果WSH曾經被移植到其他作業系統(例如麥金塔或UNIX),那麼這個抽選路徑的方法就可能會失敗。在這個情況下,您可以使用下面的架構來取代之:
path = Left(WScript.ScriptFullName), _
            Len(WScript.ScriptFullName) - Len(WScript.ScriptName))
這個敘述只是將完整的檔名與Script的檔名相減,所以他與檔案命名慣例無關。如果您不想使用這個小技巧,您可以使用FileSystemObject物件的GetParentFolderName方法,範例如下:
Dim fso
Set fso = CreateObject("Scripting.FileSystemObject")
Path = fso.GetParentFolderName(WScript.ScriptFullName)
只要Microsoft正確地實作GetParentFolderName,您便能夠取得路徑(與作業系統無關)。然而,您必須使用額外的記憶體來建立檔案系統物件,以及花費額外的時間去執行此方法。
取得目前的資料夾
 

Visual Basic和VBA(Visual Basic for Application)都有取得目前資料夾的函數。在Scirpt中,目前資料夾指的就是Script被執行的位置的那個目錄,所以您可以使用前一小節的程式碼或下面的敘述來取得目前的資料夾:
Dim fso
Set fso = WScript.CreateObject("Scripting.FileSystemObject")
' CurrentDir = fso.GetAbsolutePathName("")
' 或使用下面的語法
CurrentDir = fso.GetAbsolutePathName(".")
在這段程式碼中,FileSystemObject會藉由使用其參數為 "." 的GetAbsolutePathName方法來取得路徑。

說明
CurrentDir.vbs(位於\WSHDevGuide\Chapter14資料夾中)會在訊息盒中顯示目前的資料夾與Script的路徑。另一個方法是,您可以使用即將介紹的GetDir方法。

設定預設的資料夾
 

WSH並不提供設定程式之預設資料夾的方法,但是有幾個解決方案可用。最簡單的方法是將包含Script檔案在內的必要檔案放到資料夾中。接著您可以使用GetPath函數(您已經看過了)來指出目前資料夾的位置。
第2個方法是建立捷徑檔案、設定其執行路徑與開始位置,然後使用Run方法來執行此捷徑。從捷徑檔案啟動的應用程式會取得所有設定的參數。
第3個方法是建立包括cd命令並且會呼叫應用程式的BAT檔案。接著您便能夠使用Run方法來執行這個批次檔。(您可以在第7章和第10章找到有關建立捷徑檔案和使用Run方法的細節。)
取得目前的磁碟機名稱
 

您可藉由使用WScript物件的ScriptFullName屬性來取得目前磁碟機的名稱,但是這個方法傳回的是複雜的UNC路徑。比較簡單的方法(也是使用UNC路徑)是使用下面的程式碼:
Set oFS = WScript.CreateObject("Scripting.FileSystemObject")
oldDrive = oFS.GetDriveName(WScript.ScriptFullName)
您傳遞ScriptFullName屬性的值給FileSystemObject物件的GetDriveName方法,而此方法將傳回目前磁碟機的名稱,如圖14-1所示。

 
 圖14-1 顯示目前磁碟機的名稱(以UNC路徑格式)

說明
上面的程式碼將永遠傳回此Script被啟動之位置的磁碟機。您無法從WSH中使用其物件模型所提供的方法來改變目前的磁碟機。

計算日期差值
 

您可以在VBScript中使用DateDiff函數來計算日期差。根據VBScript的說明,您必須在第1參數指定間隔;而其餘的兩個參數則是要被用來計算差值的日期,如下所示:
WScript.Echo "距離2020年還有" & DateDiff("d", Now, "1/1/2020") & _
             "天..."
這個敘述使用「d」(day,日)間隔來計算距離2020年還剩多少天。Now會傳遞目前的日期,而第3個參數則設定了一個固定的日期值。

說明
您所使用的日期分隔符號與您作業系統的本機設定有關。

圖14-2顯示的是一連串的日期差值並顯示距離給定日期還剩多少天。有個地方出錯了,就像您在最後一行看到的:日期差值是負的。

 
 圖14-2 日期差值
讓我們來細看計算日期差值的程式碼吧!下面這兩行會計算現在和2020年1月1日之間的差值,但是使用2位數日期是有風險的:
MsgBox "距離2020年還有" & DateDiff("d", Now, "1/1/2020") & "天..."
MsgBox "距離2020年還有" & DateDiff("d", Now, "1/1/20") & "天..."
第2個敘述顯示的是負數(如圖14-2所示)。日期「1/1/20」會導致DateDiff去計算距離2001年1月20日的天數。
因此,在您的Script中使用4位數日期數值永遠是好的程式設計風格。您可以藉由使用\WSHDevGuide\Chapter14資料夾中的DateTest.vbs檔案來檢查這種狀況。
長檔名、AT命令與系統呼叫
 

在本節中,我們將涵蓋如何處理長檔名、如何使用AT命令,以及如何藉由使用Run方法來叫用系統呼叫。
使用Windows NT的排程程式來執行WSH Script
 

您可以使用Windows NT的 排程程式 在特定的時間去執行Script:
AT 18:00:00 /interactive "C:\WSHDevGuide\Chapter14\RunExit.vbs"
在AT命令列中,您必須寫Script檔案的完整路徑。如果Script需要與使用者互動,那麼您也必須設定 /interactive旗標。

說明
在Windows 98和Windows 2000中,您可以使用 排定的工作 來安排Script的執行。(雖然 排定的工作 有提供給其他程式使用的API,但是他並不支援Script程式設計介面;Microsoft網站有包含提供必須的COM介面的幫手DLL。)

在Script中使用長檔名
 

如果您的Script包含長檔名或者如果您在要執行Script的命令中使用長檔名,則您必須將這些路徑以雙引號圍起來,範例如下:
WshShell.Run _
    """C:\Programs\Microsoft Office\Office\Excel.exe""", 1, True
在VBScript中,您必須將雙引號寫成字串 """ 形式。第1個雙引號指的是字串的開始。而接下來的兩個雙引號指的是要被插入字串中的雙引號。
在JScript中,您可將雙引號寫成字串「\"」的形式:
WshShell.Run _
    ("\"C:\\Programs\\Microsoft Office\\Office\\Excel.exe\"",
    1, true);

說明
如果您藉由取得路徑名稱來建立命令列並接著以指定的檔名連接為字串,則您必須在結果字串的兩頭加上雙引號(因為取得的路徑名稱可能包含空格)。這裡有個例子:oWSH.Run """ & path & """, 3, True。4個雙引號是必要的,因為兩個內部雙引號會強制語言引擎將其識別為一個。而外部的雙引號則用來標示內部的雙引號為字串字元。

使用Run方法來執行系統呼叫
 

要從您的Script中呼叫Windows API函數,您需要提供正確介面的ActiveX控制項。(在《Advanced Development with Microsoft Windows Script Host 2.0》一書中有解釋如何撰寫這樣的控制項。)不過,Windows 95、Windows 98、Windows NT和Windows 2000有提供一些允許您從Script中藉由使用Run方法來存取系統常式的後門選項。
使用RunDll32.exe來將Windows 95或Windows 98關機
 

若您沒有提供將Windows 95或Windows 98關機的方法的ActiveX控制項,那麼您可以在Run方法中使用下面的命令:
WshShell.Run "%WINDIR%\RunDll32.exe user,ExitWindows", 1, -1
程式RunDll32.exe會啟動包含於程式庫(DLL)檔案中的數個Windows API函數。這裡顯示的命令會啟動RunDll32.exe。這個幫手程式將存取程式庫User.exe並呼叫該程式庫的ExitWindows API函數。

提示
您可以在RunDll32.exe命令中使用任何Windows DLL程式庫,但是您必須牢記一些限制。從程式庫匯出的函數的名稱是有區分大小寫的。(舉例來說,exitWindows和ExitWindows就不一樣。)還有,您不能用RunDll32.exe來傳遞參數給Windows API函數。但是有一些允許您使用RunDll32.exe來呼叫其他函數和在命令列中傳遞字串的例外。因為這些函數(例如,後面將討論到的SHExitWindowsEx)會以參數來測試命令列。

程式14-1中所顯示的VBScript程式包含要從WSH Script中將Windows 95或Windows 98關機的命令。
 程式14-1 RunExit.vbs
'************************************************
' 檔案:  RunExit.vbs (WSH sample in VBScript) 
' 作者:  (c) G. Born
'
' 使用Run方法來呼叫Windows 95/98的
' ExitWindows API函數
'************************************************
Option Explicit
Dim WshShell
Set WshShell = WScript.CreateObject("WScript.Shell")
If (MsgBox("將Windows 95/98關機?", vbYesNo + vbQuestion, _
    "WSH sample - by G. Born") = vbYes) Then _
    WshShell.Run _
        "%WINDIR%\RunDll32.exe user,ExitWindows", 1, -1
'*** 程式結束

說明
這個呼叫在Windows NT或Windows 2000中是無效的,因為作業系統在User.exe中並不支援ExitWindows函數。(要在Windows NT或Windows 2000中關機需要其呼叫者的權限。)ActiveX控制項WSHExtend.ocx(請參閱《Advanced Developement with Microsoft Windows Script Host 2.0》一書)有提供將Windows 95、Windows 98、Windows NT或Windows 2000關機的方法。

將Windows 95或Windows 98關機與重新啟動的小技巧
 

剛剛顯示讓您用來將Windows 95或Windows 98關機的技巧無法被用來將系統重新啟動。然而,這些Windows版本支援不載入Windows核心而只載入MS-DOS核心的 MS-DOS模式 (Console視窗模式)。因此,如果您在 MS-DOS模式 中執行MS-DOS程式,那麼Windows便會終止。在結束MS-DOS應用程式之後,Windows核心又會自動被重新載入。這和重新啟動有相同的效果。
您可以使用 MS-DOS模式 的反應來強制Windows在Windows 95或Windows 98中被重新啟動。首先,您需要建立包含只有下面命令的BAT檔案:
@Exit
接著,您需要右擊該BAT檔案的圖示並從快顯功能表中選擇 內容 。在 程式 屬性頁次中,選取 MS-DOS模式 選項並取消 進入MS-DOS模式之前,請警告我 選項。現在,按兩下這個BAT檔案的結果將會在 MS-DOS模式 中啟動批次程式。因為此BAT檔案包含Exit命令,所以這個模式會立刻結束而Windows將重新載入。要從WSH Script中重新啟動Windows,您只要撰寫使用Run方法來執行您BAT檔案的Script即可。
這個小技巧在Windows 95和Windows 98中都可以執行得很好(但是針對Windows ME就沒有了)。若您想要更多對於關機和重新啟動程序的控制,那麼您必須存取另一個名為ExitWindowsEx的Windows API函數。這個函數在Windows 95、Windows 98和Windows NT中皆可使用。不幸的是,您無法使用RunDll32.exe程式來呼叫這個API函數,因為這個函數需要兩個參數:一個用來定義結束模式,而另一個則是保留的。沒有ActiveX控制項,您便無法使用這個API函數。
我還發現另一個在Windows 98(以及在Windows ME)中無文件記載的以需要的參數從Shell中呼叫ExitWindowsEx函數的小技巧。這個小技巧使用了在檔案Shell32.dll中的函數SHExitWindowsEx。這個函數扮演ExitWindowsEx的外殼,並且可以藉由使用下面的命令被從Windows Shell中呼叫:
RunDll32.exe Shell32.dll,SHExitWindowsEx 0x0
RunDll32.exe會呼叫Shell32.dll中的函數SHExitWindowsEx。這個函數擁有一個必須被以字串形式傳遞的參數。(這就是前面說過的例外之一:SHExitWindowsEx支援從命令列傳遞過來的參數。)傳遞過來的參數會指定一個十六進位數字當作結束模式的參數。字串0x0用來指定數值0,而0x1用來指定數值1等等。SHExitWindowsEx會讀取這個參數、將其轉換為十六進位的數字,並以所需的參數來呼叫原始的API函數ExitWindowsEx。表14-1列出了您可以用於此參數的數值。
 表14-1 SHExitWindowsEx參數值
參數結果
0x0登出
0x1關機
0x2重新啟動
很明顯地,您可以使用RunDll32.exe來強制Windows 98關機或重新啟動,或者強制使用者登出。程式14-2是實作表14-1的WSH Script。
 程式14-2 RunExitEx.vbs
'************************************************
' 檔案:  RunExitEx.vbs (WSH sample in VBScript) 
' 作者:  (c) G. Born
'
' 使用Run方法來呼叫無文件記載的Windows 98
' SHExitWindowsEX API函數來關機、重新啟動或登出
' 
' Shell32.dll,SHExitWindowsEx,0x0登出
' Shell32.dll,SHExitWindowsEx,0x1關機
' Shell32.dll,SHExitWindowsEx,0x2重新啟動
'************************************************
Option Explicit
Dim Shell, Title, obj
Title = "WSH sample - by G. Born"

' 建立Shell物件
Set Shell = WScript.CreateObject("Shell.Application")
Set obj = WScript.CreateObject("WScript.Shell")

' 呼叫登出模式
If (MsgBox("登出?", _
    vbYesNo + vbQuestion, Title) = vbYes) Then
    obj.Run "RunDll32.exe Shell32.dll,SHExitWindowsEx 0x0" 
Else
    ' 呼叫關機
    If (MsgBox("將Windows關機?", _
        vbYesNo + vbQuestion, Title) = vbYes) Then
        obj.Run "RunDll32.exe Shell32.dll,SHExitWindowsEx 0x01" 
    Else
        ' 呼叫重新啟動模式
        If (MsgBox("重新啟動Windows?", _
            vbYesNo + vbQuestion, Title) = vbYes) Then
            obj.Run "RunDll32.exe Shell32.dll,SHExitWindowsEx 0x02"
        End If
    End If
End If
'*** 程式結束
這個呼叫在Windows 95、Windows NT或Windows 2000中並不能運作,因為這些作業系統並未支援這個幫手函數。稍後當說明到如何存取Windows 98 Shell以便暫停您的機器或叫用 Windows關機 對話盒時將回到這個主題。
鎖定Windows 2000工作站
 

雖然您不能使用RunDll32.exe呼叫來結束Windows NT或Windows 2000,但是您可以鎖定Windows 2000 Professional工作站。在Windows 2000中,模組User32提供了LockWorkStation API函數呼叫。程式14-3中的程式碼使用RunDll32.exe來呼叫此API函數並鎖定系統。
 程式14-3 NTLockWorkStation.vbs
'********************************************************
' 檔案: NTLockWorkStation.vbs (WSH sample in VBScript) 
' 作者: (c) G. Born 
'
' 鎖定Windows 2000工作站
'********************************************************
Option Explicit
Dim WshShell
' 建立WshShell物件(以便使用Run方法)
Set WshShell = WScript.CreateObject("WScript.Shell")

' 詢問使用以允許鎖定
If MsgBox("鎖定工作站?", vbYesNo, "WSH Sample") = vbYes Then
    ' 使用LockWorkStation API呼叫
    WshShell.Run "RunDll32.exe user32.dll,LockWorkStation"
End If

'*** 程式結束
使用者可以按兩下這個檔案來鎖定工作站。在使用者輸入密碼之後, 桌面 與所有開啟的視窗都會恢復。這個範例本身並非十分的有用(因為您可藉由使用 Ctrl+Alt+Del 然後按下 鎖定電腦 鈕來鎖定您的工作站)。但是他示範的技巧在Script執行期間可能會非常方便。
叫用複製磁碟對話盒
 

Windows使用DiskCopy.dll內部地處理兩片磁碟片之間的複製工作。您可以呼叫這個程式庫來叫用 複製磁碟 對話盒(如圖14-3所示)。

 
 圖14-3 複製磁碟 對話盒
這個DLL匯出可以被從其他程式中呼叫的函數。您可以從WSH Script中使用RunDll32.exe來呼叫DiskCopy.dll中的DiskCopyRunDll項目,其命令如下:
RunDll32.exe DiskCopy.dll,DiskCopyRunDll
這個命令會叫用 磁碟複製 對話盒。程式14-4會從WSH Script中存取 複製磁碟 對話盒。
 程式14-4 CopyDisk.vbs
'************************************************
' 檔案:  CopyDisk.vbs (WSH sample in VBScript)
' 作者:  (c) G. Born
'
' 叫用【複製磁碟】對話盒
'************************************************
Option Explicit
Dim WshObj      ' 支援Run方法的物件

 
Set WshObj = Wscript.CreateObject("WScript.Shell")

WshObj.Run _
    "RunDll32.exe DiskCopy.dll,DiskCopyRunDll", _
    1, True ' 啟動對話盒

'*** 程式結束
叫用格式化對話盒
 

您可以使用類似的技巧在Windows中叫用 格式化 對話盒來格式化磁碟片。格式化函數被實作於Shell32.dll檔案中;您可藉由使用會顯示 格式化 對話盒的SHFormatDrive呼叫來叫用他。下面的命令會從WSH Script中存取這個函數:
RunDll32.exe Shell32.dll,SHFormatDrive
程式14-5中的Script會叫用 格式化 對話盒。
 程式14-5 Format.vbs
'**************************************************
' 檔案:  Format.vbs (WSH sample in VBScript) 
' 作者:  (c) G. Born
'
' 叫用【格式化】對話盒來格式化磁碟片
'**************************************************
Option Explicit
Dim WshObj      ' 提供Run方法的物件

Set WshObj = Wscript.CreateObject("WScript.Shell")

WshObj.Run "RunDll32.exe Shell32.dll,SHFormatDrive", _
           1, True ' 啟動對話盒
'*** 程式結束
叫用螢幕保護程式內容頁次
 

 螢幕保護程式 內容頁次允許您安裝螢幕程式。您可以從Script或從Windows Shell中藉由使用下面的命令來叫用這個內容頁次:
RunDll32.exe desk.cpl,InstallScreenSaver
程式14-6會使用VBScript來叫用內容頁次。
 程式14-6 ScreenSaver.vbs
'************************************************
' 檔案:  ScreenSaver.vbs (WSH sample in VBScript)
' 作者:  (c) G. Born
'
' 安裝螢幕保護程式
'************************************************
Option Explicit
Dim WshObj      ' 支援Run方法的物件

Set WshObj = Wscript.CreateObject("WScript.Shell")

WshObj.Run _
    "RunDll32.exe desk.cpl,InstallScreenSaver", _
    1, True ' 【螢幕保護程式】內容頁次

'*** 程式結束
呼叫控制台模組
 

前面的範例介紹了使用RunDll32.exe來叫用 螢幕保護程式 內容頁次的方法。您也可以在Run方法中使用Control.exe取代RunDll32.exe透過.cpl檔案來叫用 控制台 內容頁次。下面的命令將叫用 滑鼠內容 對話盒的 按鈕 內容頁次:
WshObj.Run "Control.exe main.cpl,@0,0"
跟在模組(.cpl檔案)名稱後面的參數用來指定該模組的哪個屬性頁次要被顯示在前景中。表14-2是一些模組與其參數的列表。
 表14-2 控制台模組與其參數
模組名稱索引說明範例
Appwiz.cpl0到3開啟 新增/移除程式 對話盒中的「索引」所指的屬性頁次。Control.exe Appwiz.cpl,,1
Desk.cpl0到3開啟 顯示 對話盒的某個頁次。Control.exe Desk.cpl,,1
Intl.cpl0到4開啟 地區選項 對話盒並選擇頁次。第2個參數用來定義屬性頁次。Control.exe Intl.cpl,,1
Main.cpl@0到@50到x支援 滑鼠、鍵盤、電源選項  PCMCIA 等內容對話盒。第1個參數用來指定模組。您可以使用名稱(例如,Mouse或Key- board)或者使用@x(其中x是從0到5之數值的佔位符號)格式的索引值。第2個參數用來指定模組的屬性頁次。Control.exe Main.cpl,@0,1Control.exe Main.cpl,Mouse,1
Mmsys.cpl@0、@10到x開啟 聲音及多媒體 的內容對話盒。第1個參數用來指定內容對話盒(0表示「多媒體」;1表示「聲音」)。第2個參數用來指定屬性頁次。Control.exe Mmsys.cpl,@0,1
Sysdm.cpl0到3開啟 系統 內容對話盒並選擇某個頁次。Control.exe Sysdm.cpl,,0
Timedate.cpl0、1開啟 時間/日期 內容 對話盒。Control.exe Timedate.cpl,,0
這些內容對話盒的名稱會因作業系統的版本而有一些差異。而屬性頁次的數目也會不同。表14-2顯示的是Windwos 98(大部分的東西都可以在Windows 95、Windows NT和Windows 2000中被使用)的選項。
使用Run方法來處理網路對應
 

您可以使用WshNetwork物件來處理磁碟機或印表機的網路對應,但是有些時候藉由使用這個物件及其方法來改變網路設定可能會顯得有些太複雜。有個簡單的方法是一起使用Run方法和MS-DOS的Net命令。舉例來說,要刪除機器上所有的網路對應,您可以在Script中使用下面的命令:
Set objSh = WScript.CreateObject("WScript.Shell")
objSh.Run "NET USE * /DELETE /YES", 0, True
NET USE命令會存取網路對應。萬用字元(*)用來定義所有的對應,而選項 /DELETE則會移除這些對應。選項 /YES會強制此動作而無須詢問使用者。

說明
更多有關NET命令的資訊,請開啟 命令提示字元 視窗並輸入「NET /?」或「NET USE /?」便能看見說明頁。

使用者對話盒與輸出
 

我們已經看過很多在使用者對話盒中顯示Script輸出的範例了。現在筆者想要分享一些在使用者對話盒中處理Script輸出的提示和程式設計技巧。此外也將討論 命令提示字元 視窗(Console)中的輸入與輸出串流,並提供一些在WSH Script中列印不同文件類型的提示。
使用水平定位與換行
 

當您在傳遞字串給前面章節中提過的對話盒方法(例如Echo和Popup)和函數(例如MsgBox)時,字串會被自動格式化以適合對話盒的大小。但是您可以插入水平定位與換行字元到字串中以便格式化輸出為您想要的樣子。VBScript使用預先定義的vbCrLf常數來強制換行:
WScript.Echo "第1行" & vbCrLf & "第2行"
而在JScript中,您可以加入跳脫字元 \n(新行)到字串中:
WScript.Echo("第1行\n第2行");
要在對話盒中格式化欄位,您可以插入水平定位字元到文字中。在VBScript,您可藉由在您的字串中使用命名常數vbTab來達到這個目的。而在JScript中,您可以插入跳脫字元 \t到字串中以強制水平定位。水平定位的位置在對話盒中是固定的。

程式輸出導管
 
 命令提示字元 視窗中,管道(Pipe)機制允許您使用程式的輸出當作另一個程式的輸入。下面的命令使用dir命令的輸出來當作more篩選器的輸入:
dir *.* | more
您可以使用類似的命令來導向某些輸入給Script程式。讓我們假設程式StdIOFilter.vbs讀取預設的串流當作輸入。我們可以輸入這個命令來讓命令提示字元執行dir命令:
dir *.* | CScript.exe StdIOFilter.vbs
dir輸出將被導向當作Script程式的輸入。使用CScript.exe來呼叫主機是很重要的。StdIOFilter.vbs可以讀取標準輸入串流、處理輸入,並將結果寫入標準輸出中。程式14-9會讀取輸入串流、新增前置與後置行、轉換所有字元為大寫,並將結果寫到預設的輸出串流中。
 程式14-9 StdIOFilter.vbs
'***************************************************
' 檔案:  StdIOFilter.vbs (WSH 2 sample in VBScript) 
' 作者:  (c) G. Born
'
' 讀取輸入資料並將之傳送到輸出串流中
'***************************************************
Option Explicit
Dim tmp
' 現在讀取輸入串流
tmp = WScript.StdIn.ReadAll( )

' 試著將結果寫到標準輸出串流中
WScript.StdOut.WriteLine("*** 輸出篩選器示範 ***")
WScript.StdOut.Write(UCase(tmp))
WScript.StdOut.WriteLine("*** 輸入資料的結尾 ***")

'*** 程式結束

說明
要啟動StdIOFilter.vbs,您必須使用上面顯示的命令。您無法使用IsCScript函數來執行CScript.exe的第2份副本,因為WSH實際上並不能處理輸入與輸出串流。

使用檔案串流
 

讓我們看看Script該如何使用TextStream物件從文字檔中讀取資料、處理資料並顯示之。我們的VBScript範例程式可以在CScript.exe或WScript.exe下執行。他會執行用來建立磁碟機C:\目錄列表的dir命令並將輸入重新導向(Redirect)到暫存檔中。然後Script會讀取此暫存檔並移除開頭的磁碟標籤名稱(Volume Name)。接著他會從目錄清單中刪除日期和時間欄位。其結果(包括兩行總結)將被顯示於對話盒中。
這個範例Script示範了一些新的技巧。首先,他會使用FileSystemObject物件的方法在系統的暫存資料夾中建立暫存檔:
Set fso = CreateObject("Scripting.FileSystemObject")
tmp = fso.GetTempName
變數tmp包含由作業系統所產生之暫存檔的名稱。接著您找出作業系統用來儲存暫存檔的資料夾的路徑。您可以使用GetSpecialFolder方法來取得此資料夾的位置:
path = fso.GetSpecialFolder(tmpFolder)
tmpFolder參數必須被設為常數值2。

說明
tmpFolder的參數若為數值0將會傳回Windows資料夾的路徑。而數值1會傳回系統資料夾的路徑。在前面的章節中,曾經提到系統資料夾與作業系統有關。Windows 95和Windows 98使用\System資料夾,而Windows NT和Windows 2000則使用\System32。因此,您可以使用GetSpecialFolder與數值1來取得與作業系統無關的系統資料夾的位置與名稱。

在取得暫存資料夾的路徑之後,您可以建立暫存檔的絕對路徑:
tmp = path & "\" & tmp
下面這兩個敘述會執行建立包含其命令之結果的暫存檔的dir命令:
Set WshShell = CreateObject("WScript.Shell")
WSHShell.Run "%comspec% /c " & cmd & " >" & tmp, 0, True
變數 %comspec% 包含命令處理器的名稱。第2個參數被設為0(一般視窗大小),而第3個參數則被設為True以便強制Script暫停直到命令結束為止。
下面的命令會開啟暫存檔並傳回與此檔案關聯的TextStream物件:
Set oFile = fso.OpenTextFile(tmp)
您接著可以使用下面的迴圈來略過前4行:
For i = 1 to 4
    oFile.SkipLine
Next
下一個敘述會讀取暫存檔其餘的部分到字串變數txt中:
txt = oFile.ReadAll
在暫存檔被檔取完畢之後,您可以使用下面的命令來關閉並刪除之:
oFile.Close 
fso.DeleteFile tmp
變數txt在單行中包含檔案的內容。如果您想要一行一行地處理這個內容,那麼您可以使用Split函數:
lines = Split(txt, vbCrLf)
這個函數會分裝(以第2個參數給定的分隔符號)字串到陣列中。然後您可以使用陣列元素lines(0)、lines(1) 等來存取行。
接著,您可以使用下面的命令來將陣列加入單一字串中:
txt = Join(lines, vbCrLf)
Join函數會將第2個參數傳遞過來的式樣加入每一行中並將結果儲存到字串。完整的VBScript範例如程式14-10所示。這個Script會顯示兩個對話盒,第1個包含dir命令的原始輸出,而第2個顯示的是篩選過的資料(拿掉時間與日期)。
 程式14-10 Pipe.vbs
'************************************************
' 檔案:  Pipe.vbs (WSH 2 sample in VBScript) 
' 作者:  (c) G. Born
'
' 在MS-DOS命令之間交換資料和
' 使用暫存檔的Script
'************************************************
Option Explicit
Const cmd = "dir c:\*.* /ON"   ' 要被執行的命令
Const tmpFolder = 2            ' 系統的暫存資料夾

Dim WshShell, fso, oFile, tmp, path, txt, lines, i
' 建立FileSystemObject
Set fso = CreateObject("Scripting.FileSystemObject")

' 取得暫存檔名
tmp = fso.GetTempName     

' 取得系統暫存資料夾的路徑
path = fso.GetSpecialFolder(tmpFolder)
tmp = path & "\" & tmp     ' 建立暫存檔路徑

' 現在我們擁有一個暫存檔囉
' 建立WshShell物件...
Set WshShell = CreateObject("WScript.Shell")
' ...並執行重新導向輸出到暫存檔的MS-DOS命令
WSHShell.Run "%comspec% /c " & cmd & " >" & tmp, 0, True

' MS-DOS命令完成囉!暫存檔現在存在包括dir命令的輸出了
' 讀取檔案的內容
Set oFile = fso.OpenTextFile(tmp)

' 略過前幾行
For i = 1 to 4
        oFile.SkipLine
Next
txt = oFile.ReadAll                ' 檔案其餘的部分
oFile.Close 
fso.DeleteFile tmp                 ' 刪除暫存檔

WScript.Echo txt     ' 顯示內容
' 這裡我們試著去處理其內容
' 首先,將所有行分裝到陣列中
lines = Split(txt, vbCrLf)
' 忽略最後2行
For i = 1 to UBound(lines) - 3 
    lines(i) = Mid(lines(i), 40)   ' 拿掉日期與時間
Next
' 將陣列的資料加入字串中並顯示之
MsgBox Join(lines, vbCrLf)

'*** 程式結束
記錄Script的輸出
 

要記錄Script的輸出到檔案中,您可以使用WshShell物件(由WSH 2提供)的LogEvent方法。這個方法會附加資料到記錄檔中。在Windows NT和Windows 2000中,這些項目會被放入系統的記錄檔中;您可以在 事件檢視器 中檢視他,如圖14-5所示。

 
 圖14-5  事件檢視器 中檢視記錄項目
在Windows 95和Windows 98中,事件會被附加到使用者Windows資料夾中的檔案WSH.log內。這個項目被撰寫為日期與時間、事件類型以及被傳遞給LogEvent方法的文字。要呼叫這個方法,您可以使用下面的程式碼:
Set WshShell = WScript.CreateObject("WScript.Shell")
flag = WshShell.LogEvent(INFORMATION, Text)
WScript.Shell物件的LogEvent方法需要兩個參數。第1個參數用來定義事件類型而其值介於0到16之間。第2個參數則包含要用附加到記錄檔中的文字。如果此方法成功,那麼True值便會被傳回;反之,則傳回False值。
讓我們來看一個在每次使用者登入到機器上時都會記錄日期、時間、電腦名稱、網域和使用者名稱到記錄檔中的小型VBScript程式吧!他首先會收集將被放入記錄檔中的資料。所需的資料都被包含於WshNetwork物件的屬性中,所有您可以建立一個包含所需資料的文字變數:
Text = Date & "  " & Time & vbTab & "電腦:" & _
       WshNetwork.ComputerName & vbTab
Text = Text & "網域:" & _
       WshNetwork.UserDomain & vbTab
User = WshNetwork.UserName      ' 初始化數值
Do While User = ""              ' 直到使用者名稱被傳回的迴圈
    WScript.Sleep 200           ' 暫停以便降低CPU的負擔
    User = WshNetwork.UserName  ' 讀取屬性
Loop
Text = Text & "使用者:" & User & vbTab
因為這個範例只有在Windows 95或Windows 98系統中是有意義的(Windows NT和Windows 2000在預設的情況下便會記錄使用者的登入),所以我使用在第11章提過的技巧來等待直到UserName屬性傳回有效的名稱。您可藉由使用下面的程式碼來將這個字串寫入到記錄檔中:
WshShell.LogEvent INFORMATION, Text
這個呼叫並不會傳回任何值,因為我們使用的是程序呼叫。所以您該如何強制Windows 95或Windows 98在每次使用者登入時執行這個Script呢?您可以加入包括Script的路徑和檔名的命令到下面這個登錄機碼的數值UserLog中:
HKLM\\Software\Microsoft\Windows\CurrentVersion\Run
這個機碼的內容在每次使用者登入時都會被處理。程式14-11顯示的是會在每次執行時都新增命令到Run機碼中的Script。使用者必須只啟動這個Script一次來強制自動執行。要從登錄中移除這個項目,您可以使用 系統原則編輯器  登錄編輯程式 或(Windows 98中的) 系統設定工具 
 程式14-11 UserLog.vbs
'*******************************************************
' 檔案:  UserLog.vbs (WSH 2 sample in VBScript) 
' 作者:  (c) G. Born
'
' 使用WSH 2的LogEvent方法來寫入使用者名稱
' 這個script被加入到Run機碼中,所以要在Windows 95
' 和Windows 98中建立使用者記錄函數就變得很方便了
'*******************************************************
Option Explicit 
Const SUCCESS = 0 
Const ERROR = 1 
Const WARNING = 2 
Const INFORMATION = 4
Const AUDIT_SUCCESS = 8
Const AUDIT_FAILURE = 16 

Dim Text, User
Dim WshNetwork, WshShell         ' 物件變數

' 建立WshShell物件的參考
' (以提供所需的登錄存檔和EventLog方法)
Set WshShell = WScript.CreateObject("WScript.Shell")

' 將Script加到Run機碼中以便他會在每次當入時被執行
AddRun                 

' 建立新的WshNetwork物件來存取網路屬性
Set WshNetwork = WScript.CreateObject("WScript.Network")

Text = Date & "  " & Time & vbTab & "電腦:" & _
       WshNetwork.ComputerName & vbTab
Text = Text & "網域:" & _
       WshNetwork.UserDomain & vbTab
User = WshNetwork.UserName        ' 初始化數值
Do While User = ""                ' 直到使用者名稱被傳回的迴圈
    WScript.Sleep 200             ' 暫停以便降低CPU的負擔
    User = WshNetwork.UserName    ' 讀取屬性
Loop
Text = Text & "使用者:" & User & vbTab
' 撰寫記錄檔項目。傳回True(成功)或False(失敗)
If WshShell.LogEvent(INFORMATION, Text) Then
    ' 移除靜止的使用
    WScript.Echo "寫入記錄事件:" & vbCrLf & vbCrLf & Text  ' 顯示結果
Else
    WScript.Echo "LogEvent方法在UserLog.vbs中失敗了!"
End If
Sub AddRun( )
    ' 加入啟動此Script的批次檔到登錄的Run機碼中
    Dim Command

    Const Root = "HKEY_LOCAL_MACHINE"
    Const key = "\Software\Microsoft\Windows\CurrentVersion\Run\"
    Const valname = "UserLog"

    Command = WScript.ScriptFullName
    WshShell.RegWrite Root & Key & valname, Command, "REG_SZ"
End Sub
'*** 程式結束
從WSH Script中列印
 

WSH並沒有列印支援,因為列印在Windows並非一件簡單的工作。要從Script中列印的唯一方法是強制某個應用程式來為您進行這項工作。要列印純文字檔,您可以使用Notepad.exe。 記事本 提供允許您列印文字檔然後在列印完畢之後關閉編輯器的 /p選項,範例如下:
Notepad /p C:\Test\Text.txt
這個命令會強制Windows載入 記事本 並傳遞命令列的參數。如果 記事本 在命令列中發現檔名,他便會試著去載入該檔案。如果他偵測到 /p選項,他將會把此檔案傳送到預設的印表機中。在列印完畢之後, 記事本 便會結束。
下面的程式碼片段(由PrintTxt.vbs中截取的)使用了這個技巧來列印Script的原始碼:
Set oWshShell = WScript.CreateObject("WScript.Shell")
' 執行使用【記事本】來列印的命令
oWshShell.Run "Notepad /p " & WScript.ScriptFullName, 7, True
第1行會建立Run方法所需之WshShell物件的物件實體。第2個敘述會執行啟動 記事本 的命令並列印指定的文字檔。這個敘述使用ScriptFullName屬性來插入Script的檔名。被傳遞給Run方法的第2個參數被設為7來強制 記事本 以最小化視窗來執行。最後面的參數被設為True是用來告訴Script等待直到從Run方法啟動的程序結束為止。
這個解決方案在處理存文字檔方面都沒有問題,但是您無法用他來改變印表機。要叫用 印表機 對話盒(在Windows 2000中)以便使用者能夠選擇印表機並設定印表機的選項,您可以使用這段程式碼:
Set oWshShell = WScript.CreateObject("WScript.Shell")
' 執行以MSHTML來列印原始碼的命令
oWShShell.Run "RunDll32.exe MSHTML.dll,PrintHTML " & _
              WScript.ScriptFullName, 7, True
' 執行以MSHTML來列印HTML文件的命令
oWshShell.Run "RunDll32.exe MSHTML.dll,PrintHTML " & _
              GetPath( ) & "TestForm.htm", 7, True
第1個敘述會建立Run方法所需的物件實體。接下來的兩個敘述則會執行Run方法。第1個敘述會列印Script的原始碼,而第2個則會列印HTML文件。這兩個敘述都使用RunDll32.exe來呼叫幫手DLL。程式庫MSHTML.dll會匯出您可以從外部程式來使用的幾個函數。其中一個函數便是PrintHTML。(請注意大小寫有別的名稱。)這個API函數會從包含文件檔名的命令列中讀取參數。在函數被叫用之後, 列印 對話盒就會被顯示出來。因此使用者可以選擇印表機、設定印表機選項,以及列印文件。

說明
PrintDocs.vbs範例允許您列印文字檔、HTML文件和.rtf格式的文件。MSHTML不能列印像是.gif圖形和.pdf等其他格式的檔案。要列印Microsoft Office文件,您可以使用Microsoft Office應用程式。這些應用程式並不支援 /p選項,但是他們支援COM介面,所以取而代之地您可以存取其物件與方法。所有的Office應用程式都包含用來列印文件的方法。筆者也寫了一個提供使用Windows Shell來列印文件之方法的ActiveX控制項。(有關更多的詳細資訊,請參閱《Advanced Development with Microsoft Windows Script Host 2.0》一書。)

檔案處理
 

在本節中,將說明一些您會覺得用來處理檔案和資料夾十分有幫助的程式設計技巧。
檢查檔案或資料夾是否存在
 

要檢查檔案是否存在,您可以使用FileSystemObject物件的FileExists方法:
Set fso = CreateObject("Scripting.FileSystemObject")
If fso.FileExists("C:\Autoexec.bat") Then
.
.
.
如果檔案存在,則FileExists便會傳回True值。
您可以藉由使用FolderExists方法來檢查資料夾是否存在:
Set fso = CreateObject("Scripting.FileSystemObject")
If (fso.FolderExists(path)) Then
.
.
.
有關更多的資訊,請參考第12章的 〈存取檔案與資料夾〉 一節。
檢查資料夾是否為空的
 

要檢查資料夾是不是空的,您可以使用下面的程式碼:
Function FolderEmpty (name)
    ' 檢查空資料夾
    Dim fso, oFolder, oFiles            ' 物件變數
    Dim i, flag

    Set fso = CreateObject("Scripting.FileSystemObject")
    Set oFolder = fso.GetFolder(path1)  ' 取得資料夾
    Set oFiles = oFolder.Files          ' 取得Files集合

    flag = True                         ' 沒有檔案
    For Each i in oFiles 
        flag = False                    ' 若檔案被發現則觸發旗標
    Next
    FolderEmpty = flag                  ' 傳回結果
End Function
如果資料夾是空白,則FolderEmpty便會傳回True值。有關更多的資訊,請參考第12章的 〈存取檔案與資料夾〉 一節。
檢查Access的資料庫是否正在使用中
 

要存取Microsoft Access的資料庫並確保.mdb檔案沒有被另一個Access連線開啟,您可以使用檔案是否存在的測試。當Access 2000開啟資料庫時,他會自動產生一個.ldb檔案。這個檔案會在Access釋放資料庫後立即消失。您可以透過檢查.ldb檔案是否存在來決定資料庫是否已經在使用中了。程式14-12中的程式會檢查資料夾中的.mdb檔案是否可以使用,然後檢查.ldb檔案是否存在。他會將結果顯示在對話盒中。
 程式14-12 MDBOpen.vbs
'*************************************************
' 檔案:  MDBOpen.vbs (WSH sample in VBScript) 
' 作者:  (c) G. Born
'
' 檢查Access 2000的資料庫是否正在使用中
'*************************************************
Option Explicit
Dim fso, path, txt
' 取得資料庫檔案的路徑
' 必須被儲存於Script的資料夾中
path = WScript.ScriptFullName
path = Left(path, InStrRev(path, "\"))

txt = "資料庫檔案不存在!"
Set fso = WScript.CreateObject("Scripting.FileSystemObject")

If (fso.FileExists(path & "Test1.mdb")) Then ' 存在?
    If (fso.FileExists(path & "Test1.ldb")) Then
        txt = "資料庫被Access鎖定了!"
    Else
        txt = "資料庫未鎖定!"
    End If
End If
WScript.Echo txt
'*** 程式結束

說明
您應該將MDBOpen.vbs和Access 2000的資料庫Test1.mdb都從\WSHDevGuide\Chapter14資料夾複製到本機資料夾中以便進行測試。這個測試若使用Access 97也是可以的。

複製檔案
 

您可以使用File物件來複製檔案。在您建立好FileSystemObject物件之後,您可藉由使用GetFile方法和Copy方法來存取檔案,範例如下:
Set fso = CreateObject("Scripting.FileSystemObject")
Set fi = fso.GetFile(file1)    ' 建立File物件
fi.Copy file2                  ' 複製file1到file2

說明
有關檔案和資料夾的更多資訊,請參閱 第12章 。

更改檔案名稱或資料夾名稱
 

您可以下面的程式碼使用File物件來更名檔案:
Set fso = CreateObject("Scripting.FileSystemObject")
Set oFile = fso.GetFile("C:\Test.txt")  ' 建立File物件
oFile.Name = "Test1.txt"                ' 指定新的名稱
在File物件被取得之後,Name屬性會被設定為新的名稱。
您可以使用類似的手法來更名資料夾:
Set fso = CreateObject("Scripting.FileSystemObject")
Set oFolder = fso.GetFolder("C:\Test")  ' 建立Folder物件
oFolder.Name = "Test1"                  ' 指定新的名稱
在Folder物件被取得之後,Name屬性會被設定為新的名稱。另一個方法是,您可以使用FileSystemObject物件的Move方法,如程式14-13的VBScript範例所示。這個範例會轉換給定的檔案系統物件為小寫。使用者可以拖曳檔案或資料夾到LCase.vbs檔案上。所有被拖曳的檔案系統物件接著都會被顯示為小寫。
 程式14-13 LCase.vbs
'***************************************************
' 檔案:  LCase.vbs (WSH sample in VBScript) 
' 作者:  (c) G. Born
'
' 轉換資料夾或檔案的名稱為小寫
' 此Script支援拖放功能
'***************************************************
Option Explicit
' 設定大小寫模組
' 改變xCase的值為False會強制Script轉換為小寫
'Const xCase = True  ' 我們想要轉換為大寫
Const xCase = False  ' 我們想要轉換為大寫
Const Title = "Lowercase converter - by G. Born"

Dim objArgs, param, i
' 試著取得參數
Set objArgs = WScript.Arguments    ' 建立物件
If objArgs.Count < 1 Then          ' 若一個參數也沒有,則結束並顯示對話盒
    MsgBox "抱歉,找不到參數!" & vbCRLF & vbCrLf & _
           "請拖曳檔案或資料夾到這個Script的圖示上。", _
           vbInformation + vbOKOnly, Title
    WScript.Quit  ' 結束Script!!!
End If
i = 0
' 試著將檔案轉換為小寫;計算每個動作
For Each param In objArgs
    If MakeCase(param, xCase) Then i = i + 1
Next
MsgBox i & " 個物件被轉換完成囉!", vbInformation + vbOKOnly, Title
Function MakeCase(file, caseFlag)
    Dim fso, oFile, path, name
    Set fso = CreateObject("Scripting.FileSystemObject")

    If fso.FileExists(file) Then
        Set oFile = fso.GetFile(file)
    Else
        If fso.FolderExists(file) Then
            Set oFile = fso.GetFolder(file)
        Else
            MakeCase = False   ' 沒有檔案系統物件
            Exit Function
        End If
    End If
    name = fso.GetFileName(file)
    path = fso.GetParentFolderName(file)

    If caseFlag Then
        oFile.Move path & "\" & UCase(name)
    Else
        oFile.Move path & "\" & LCase(name)
    End If
    Set fso = Nothing
    MakeCase = True
End Function
'*** 程式結束

說明
您可以修改LCase.vbs以便建立大寫的檔案或資料夾名稱。您只要將xCase的值從False改成True即可。有關檔案和資料夾的更詳細資訊,請參閱 第12章 。

搜尋檔案
 

要搜尋檔案,您可以使用FileSystemObject物件與其子物件和方法來取得資料夾與其子資料夾。您必須手寫處理資料夾內容並搜尋所需檔案的程式碼。要取得給定檔案出現次數的列表,您可以使用Run方法來執行MS-DOS的DIR命令,範例如下:
DIR檔名 /s > List.txt
您接著可以藉由使用TextStream物件與其方法來存取List.txt檔案。
列出所有的捷徑檔案
 

我已經建立了一個可以取得所有包含於特殊資料夾( 桌面、開始功能表 等)中之捷徑(.lnk)檔案的名稱和位置的一個VBScript小程式。他會藉由使用會傳回集合物件的SpecialFolders屬性來取得特殊資料夾的名稱。您可使用這個集合物件中的項目來取得包含於資料夾中的Files集合。
要檢查檔案是否為捷徑,請使用下面的敘述:
InStrRev(UCase(name), ".LNK")
若副檔名為.lnk,則這個函數會傳回數值 < > 0。程式14-14中的程式會尋找特殊資料夾中的.lnk檔案並將結果條列於瀏覽器視窗(如圖14-6所示)中。

 
 圖14-6 捷徑檔案的列表
 程式14-14 ListShortcuts.vbs
'****************************************************
' 檔案:  ListShortcuts.vbs (WSH sample in VBScript) 
' 作者:  (c) G. Born
'
' 列出特殊資料夾中所有的捷徑檔案
'****************************************************
Option Explicit
Const Title = "捷徑檔案"
Dim WshShell
Dim fso, fi, fc, f
Dim text, sysf, fldr

set WshShell = WScript.CreateObject("WScript.Shell")
set fso = Wscript.CreateObject("Scripting.FileSystemObject")
text = ""
For Each sysf in WshShell.SpecialFolders
    text = text & "<b>" & sysf & "中的捷徑:</b><br>"
    Set fldr = fso.getfolder(sysf)
    Set fc = fldr.files
    For Each f In fc
        If IsLnk(f) Then text = text &  f & "<br>"
    Next
    text = text & "<br>"
Next
ShowMSIE text, Title    ' 在瀏覽器視窗中顯示項目列表
 
' 幫手函數
Function IsLnk(name)
    ' 檢查檔案是否為.lnk檔案
    IsLnk = (InStrRev(UCase(name), ".LNK") <> 0)
End Function

Sub ShowMSIE(txt, title)
    Dim oIE, oDoc
    ' 建立【Internet Explorer】的Application物件
    Set oIE = WScript.CreateObject("InternetExplorer.Application")
    ' 設定瀏覽器視窗的屬性
    oIE.left = 20              ' 視窗位置
    oIE.top = 50               ' 與其他屬性
    oIE.height = 380
    oIE.width = 580
    oIE.menubar = 0            ' 無選單
    oIE.toolbar = 0
    oIE.statusbar = 0
    oIE.navigate("about:blank")  ' 建立空的HTML文件
    oIE.visible = 1              ' 顯示【Internet Explorer】

    Do While(oIE.Busy): Loop   ' 重要: 等待直到【Internet Explorer】就緒

    Set oDoc = oIE.Document    ' 取得Document物件
    oDoc.open                  ' 開啟文件
                               ' 寫入Script到文件物件中
    oDoc.writeln("<html><head><title>" & title & "</title></head>")
    oDoc.writeln("<body>" & txt & "</body></html>")
    oDoc.close                 ' 關閉文件的寫入存取權限
End Sub

'*** 程式結束
播放聲音
 

WSH並不支援聲音檔的播放。在《Advanced Development with Microsoft Windows Script Host 2.0》一書中,介紹了一些以ActiveX控制項實作的用來播放聲音方法。然而,在WSH Script中還有一些您可以播放聲音的其他方法。有個普遍的作法是使用 Windows ActiveMovie Player 。這個播放程式包含您可以如下使用的名為Amovie.ocx的ActiveX控制項:
Set oWSH = WScript.CreateObject("WScript.Shell")
oWSH.Run "RunDll32.exe %WINDIR%\Amovie.ocx,RunDll " _
         & "/play /close C:\Test\Sound.wav"
第2個命令會執行RunDll32呼叫來叫用 ActiveMovie Player 。命令列中被傳遞的參數會強制播放程式播放聲音檔以及自動關閉視窗。
Amovie.ocx並未與Windows 2000一起發行。相反的,Windows 2000用的是做同一件事的Msdxm.ocx。所以您可以使用下面的命令:
Set oWSH = WScript.CreateObject("WScript.Shell")
oWSH.Run "RunDll32.exe %WINDIR%\System32\Msdxm.ocx,RunDll " _
         & "/play /close C:\Test\Sound.wav"
這個命令會叫用 Windows Media Player 並播放指定的媒體檔(聲音或影像)。請注意在Windows 2000中位於\System32資料夾中以及在Windows 98之\System子資料夾中的.ocx檔案。
程式14-15中的VBScript範例使用了FileSystemObject物件的GetSpecialFolder方法來取得Windows系統資料夾的路徑。然後播放.wav檔。
 程式14-15 PlaySound.vbs
'************************************************
' 檔案:  PlaySound.vbs (WSH sample in VBScript) 
' 作者:  (c) G. Born 
'
' 使用Msdxm.ocx來播放聲音
'************************************************
Option Explicit
Dim fso, oWSH
Set fso = WScript.CreateObject("Scripting.FileSystemObject")
Set oWSH = WScript.CreateObject("WScript.Shell")

oWSH.Run "RunDll32.exe " & fso.GetSpecialFolder(1) & _
         "\Msdxm.ocx,RunDll " & _
         "/play /close " & _
         "C:\WSHDevGuide\Chapter14\The Microsoft Sound.wav"

'*** 程式結束
使用Internet Explorer來播放聲音
 

您也可以使用 Internet Explorer 來播放聲音檔而無須理會平台。這個聲音檔被包含於HTML檔案中,而且會在HTML檔案載入時於背景播放。處理聲音檔的程式碼如下所示:
<html>
    <head>
        <bgsound src="The Microsoft Sound.wav" loop="1">
    </head>
    <body bgcolor="#FFFFFF">
    </body>
</html>
<bgsound> 標籤會播放背景音樂。聲音檔則被指定於src屬性中。要使用Script來啟動瀏覽器、載入HTML程式碼以及播放聲音檔,您可以使用下面的程式碼:
Set oIE = WScript.CreateObject("InternetExplorer.Application")
oIE.Navigate GetPath( ) & "Sound.htm"  ' 擁有聲音的HTML網頁
瀏覽器仍然是看不見的,因為您並不需要他。(oIE.Visible = 0是預設的設定。)因此,您並不需要設定瀏覽器視窗的大小與式樣的屬性。上面這兩行敘述就夠了。
還有一個問題:Script必須關閉瀏覽器,但瀏覽是獨立執行的程序,所以聲音檔已經被播放時Script還是不知道。在第13章中,您學過如何使用Sleep方法來暫停Script達給定的時間。您可以在 Internet Explorer 被假設已經播放聲音檔的期間使用這個技巧來暫停Script。當Script繼續執行時,他可以呼叫Quit方法來結束瀏覽器。然而,若您使用Sleep方法那麼使用者將無法停止播放聲音。
比較好的解決方案是使用Popup方法:
oWSH.Popup "Hello, world", 10
第2個參數會強制Popup在10秒鐘之後關閉對話盒。開啟的對話盒也會暫停Script的執行,所以程式在那段期間內將不會增加CPU的負擔。
如果使用者不想聽到聲音,那麼他可以按下 確定 鈕來關閉對話盒。這將導致Script呼叫瀏覽器的Quit方法而中斷聲音的播放並結束瀏覽器,如下所示。
oIE.Quit
程式14-16中的小型VBScript程式會啟動 Internet Explorer 、載入Sound.htm檔案,並暫停Script的執行達指定的時間週期。瀏覽器視窗仍然是隱藏的;使用者只看到兩個對話盒,一個用來延遲Script,而另一個則用來回報程式的結果。
 程式14-16 PlaySound1.vbs
'*************************************************
' 檔案:  PlaySound1.vbs (WSH sample in VBScript) 
' 作者:  (c) G. Born
'
' 使用第4或第5版的【Internet Explorer】來播放
' 聲音檔並使用Popup方法來暫停Script
'*************************************************
Option Explicit
Const delay = 10      ' 暫停時間的秒數

Dim oIE, oWSH         ' 宣告變數
Dim path

' 建立WshShell物件參考(為Popup方法而建立的)
Set oWSH = WScript.CreateObject("WScript.Shell")

' 啟動【Internet Explorer】
Set oIE = WScript.CreateObject("InternetExplorer.Application")
oIE.Navigate GetPath( ) & "Sound.htm"  ' 擁有聲音的HTML網頁
oIE.Visible = 0         ' 不顯示

' 重要: 等待直到IE就緒為止
 Do While (oIE.Busy): Loop
' 延遲直到聲音被播放
oWSH.Popup "Script會暫停" & delay & "秒," _
           & "因為我們正在播放聲音" & vbCrLf & vbCrLf & _
           "請按下【確定】鈕以中斷聲音!", delay, _
           "聲音示範", vbInformation + vbSystemModal

oIE.Quit             ' 關閉【Internet Explorer】

MsgBox "聲音播放完畢!", vbInformation + vbSystemModal
 
' Helper function
Function GetPath( )
    ' 取得Script路徑
    Dim path
    path = WScript.ScriptFullName
    GetPath = Left(path, InStrRev(path, "\"))
End Function
'*** 程式結束
Windows Shell
 

如果您的電腦上有安裝第4版或最更版的 Internet Explorer ,那麼您便可以存取一些Windows Shell的函數。在本節中,將示範一些從Script中使用Windows之Shell物件的超棒技巧。

說明
即將使用的範例需要第4.71版或更新版的Windows Shell。第4.71版會與 Internet Explorer 4 一起被安裝,如果有 動態桌面 功能。Windows 98本身用的是第4.72版的Windows Shell,而Windows 2000用的則是第5版的。只有Windows 95和Windows NT 4的使用者必須檢查Shell32.dll是否包含正確的版本。請注意,在機器上安裝 Internet Explorer 5 並不會更新Shell。您必須安裝 Internet Explorer 4  動態桌面 功能,然後再升級到 Internet Explorer 5 

檢驗Shell的版本
 

要檢驗您的Windows Shell是否為正確的版本,您可以使用程式14-17中這個小型的VBScript程式。這個程式需要WSH 2。Shell32.dll的路徑被設定為供Windows NT或Windows 2000使用。要在Windows 95或Windows 98中使用這個Script,您必須解除第2個敘述的註解,以便設定供Windows 95和Windows 98使用的路徑。
 程式14-17 GetShellVersion.vbs
'********************************************************
' 檔案:  GetShellVersion.vbs (WSH 2 sample in VBScript) 
' 作者:  (c) G. Born
'
' 取得Shell32.dll程式庫檔案的版本
'********************************************************
Option Explicit
Dim fso, oShell                 ' 物件變數
Dim file, tmp                   ' 檔名

' 取得Shell32.dll的路徑
' 在Windows NT和Windows 2000中,這個檔案是位於
file = "%WINDIR%\System32\Shell32.dll"
' 在Windows 95和Windows 98中,這個檔案是位於
'file = "%WINDIR%\System\Shell32.dll"

Set oShell = WScript.CreateObject("WScript.Shell")
file = oShell.ExpandEnvironmentStrings(file)

' 建立FileSystemObject物件來存取檔案系統
Set fso = CreateObject("Scripting.FileSystemObject")

' 檢查檔案是否存在
If fso.FileExists(file) Then
    tmp = fso.GetFileVersion(file)    ' 取得版本
    If Len(tmp) > 0 Then
        WScript.Echo "檔案:" & file & vbCrLf & vbCrLf & _
                     "版本:" & tmp
    Else
        WScript.Echo "檔案:" & file & vbCrLf & vbCrLf & _
                     "版本:未定義!"
    End if
Else
    WScript.Echo "找不到檔案「" & file & "」!"
End If
'*** 程式結束
排列桌面上的視窗
 

如果您曾經自訂過您的 桌面 以便將像是 全部最小化  視窗左右並排 這類的快顯功能表項目放在您的工具列上,那麼您應該知道這麼做會是非常便利的─舉例來說,在系統啟動之後最小化所有開啟的資料夾。要使用WSH Script來自動化這項工具,您可以使用Windows Shell的數個物件、方法和屬性。
首先您可藉由使用下面的敘述來建立Application物件:
Set Shell = WScript.CreateObject("Shell.Application")
這個物件提供下面的方法來操作您 桌面 上的視窗:
  •  MinimizeAll(全部最小化) 最小化您 桌面 上所有開啟的視窗並將他們顯示為工具列上的按鈕。
     
  •  UndoMinimizeAll(取消全部最小化) 取消上一個動作。最小化的視窗會回到他們之前的狀態。
     
  •  TileHorizontally(水平排列) 水平排列 桌面 上所有開啟的視窗。
     
  •  TileVertically(垂直排列) 垂直排列 桌面 上所有開啟的視窗。
     
  •  CascadeWindows(重疊視窗) 重疊 桌面 上所有開啟的視窗。
     
程式14-18中的VBScript程式會顯示數個詢問使用者是否要最小化或水平排列或垂直排列 桌面 視窗的對話盒,如圖14-7所示。這個Script還提供有每個步驟的Undo函數,所以您可以測試這些方法是如何運作的。
要取消最新一次的動作,您可以使用一個小技巧。舉例來說,在藉由使用TileVertically方法來排列視窗之後,您可以使用UndoMinimizeAll方法(雖然他的名稱令人聯想起不同的動作)來取消這個步驟。

 
 圖14-7 使用WSH Script來操作 桌面 視窗
 程式14-18 Shell.vbs
'***************************************************
' 檔案:  Shell.vbs (WSH sample in VBScript) 
' 作者:  (c) G. Born
'
' 從WSH Script中存取Windows Shell並且最小化
' 以及水平或垂直排列【桌面】上的視窗
'***************************************************
Option Explicit
Dim Shell, Title
Title = "WSH sample - by G. Born"
' 建立Shell物件
Set Shell = WScript.CreateObject("Shell.Application")

If (MsgBox("最小化所有視窗?", _
           vbYesNo + vbQuestion, Title) = vbYes) Then 
    Shell.MinimizeAll           ' MinimizeAll方法
    WScript.Echo "取消全部最小化!"
    Shell.UndoMinimizeAll       ' 復原視窗
End If
If (MsgBox("重直排列視窗?", _
           vbYesNo + vbQuestion, Title) = vbYes) Then 
    Shell.TileVertically        ' 垂直地
    WScript.Echo "取消重直排列!"
    Shell.UndoMinimizeAll       ' 復原視窗
End If
If (MsgBox("水平排列視窗?", _
           vbYesNo + vbQuestion, Title) = vbYes) Then
    Shell.TileHorizontally    
    WScript.Echo "取消水平排列!"
    Shell.UndoMinimizeAll        ' 復原視窗
End If
If (MsgBox("重疊所有視窗?", _
           vbYesNo + vbQuestion, Title) = vbYes) Then
    Shell.CascadeWindows    
    WScript.Echo "取消重疊視窗!"
    Shell.UndoMinimizeAll         ' 復原視窗
End If
WScript.Echo "就緒?"
'*** 程式結束
開啟資料夾視窗
 

您可以使用Run方法來啟動 檔案總管 並瀏覽資料夾視窗。另一個方法是,您可以從Script中使用Shell物件的Open和Explore方法以「Shell」模式(單一窗格)或「瀏覽」模式(兩個窗格)來開啟資料夾。這兩個方法都需要所需資料夾的路徑當作參數。程式14-19中的範例使用了這些方法在 檔案總管 中開啟Windows資料夾,然後開啟\System子資料夾當作資料夾視窗(以Shell模式)。
 程式14-19 Shell1.vbs
'************************************************
' 檔案:  Shell1.vbs (WSH sample in VBScript) 
' 作者:  (c) G. Born
'
' 存取Windows Shell並開啟資料夾視窗
'************************************************
Option Explicit
Dim Shell, wsh, Title, path
Title = "WSH sample - by G. Born"
' 建立WshShell物件
Set wsh = WScript.CreateObject ("WScript.Shell")

' Windows目錄
path = wsh.ExpandEnvironmentStrings("%WINDIR%")

' 建立Windows Shell的Application物件
Set Shell = WScript.CreateObject ("Shell.Application")

' 在【檔案總管】視窗中開啟資料夾
WScript.Echo "檔案總管資料夾"

' 這將以資料夾樹狀目錄開始位置為指定的路徑來執行【檔案總管】
' (與wsh.Run "explorer.exe /e,/root," & path一樣)
Shell.Explore path

' 在Shell視窗中顯示資料夾
WScript.Echo "開啟Windows資料夾的\System子資料夾"
Shell.Open path & "\System"

WScript.Echo "就緒?"
'*** 程式結束
存取Windows Shell對話盒
 

Windows Shell有一些您可以使用工具列和 開始 功能表來叫用的整合對話盒,包括 執行、搜尋 和 日期/時間 對話盒。Shell也提供您可以從Script中使用的自動化物件介面。下面的敘述會取得Shell的物件實體:
Set oShell = WScript.CreateObject ("Shell.Application")
您可以使用Windows的Shell物件的方法來叫用這些對話盒或開啟 控制台 資料夾以及 控制台 中的內容對話盒。您可使用ControlPanelItem方法來存取 控制台 
oShell.ControlPanelItem
您可以所需模組(例如Desk.cpl)的名稱當作這個方法的參數。如果您傳遞空字串,則 控制台 資料夾便會開啟。
舉例來說,要開啟 執行 對話盒,您只要應用Windows Shell物件的FileRun方法即可。下面的敘述會開啟 執行 對話盒並顯示最後輸入的命令:
oShell.FileRun
要叫用 搜尋 對話盒來搜尋檔案和資料夾,您可以使用這個方法:
oShell.FindFiles
要叫用這個對話盒來搜尋電腦,您可以使用這個方法:
oShell.FindComputer
若您需要內容頁次來設定目前的日期和時間,那麼您可以使用SetTime方法:
oShell.SetTime
我已經提過好幾個將Windows 95或Windows 98關機的技巧。Shell物件也有兩個暫停電腦(啟動省電模式)或將Windows關機的方法。下面的命令會開始Windows的Suspend方法。(Suspend方法的效果與您的機器和環境有關。)
oShell.Suspend
您可藉由使用下面的命令來叫用 Windows關機 對話盒(如圖14-8所示):
oShell.ShutdownWindows

 
 圖14-8 Windows關機 對話盒
程式14-20中的VBScript程式會顯示剛剛說過的那幾個對話盒。
 程式14-20 Shell2.vbs
'************************************************
' 檔案:  Shell2.vbs (WSH sample in VBScript) 
' 作者:  (c) G. Born
'
' 存取Windows Shell並叫用幾個對話盒
'************************************************
Option Explicit
Dim Shell, wsh, Title, path
Title = "WSH sample - by G. Born"
' 建立WshShell物件
Set wsh = WScript.CreateObject ("WScript.Shell")

' 建立Windows Shell的Application物件
Set Shell = WScript.CreateObject ("Shell.Application")

' 叫用【控制台】資料夾
If (MsgBox("開啟【控制台】?", _
           vbYesNo + vbQuestion, Title) = vbYes) Then 
    Shell.ControlPanelItem ""  ' 沒有參數
End If
' 現在試著開啟模組Desk.cpl
If (MsgBox("顯示【顯示】屬性?", _
           vbYesNo + vbQuestion, Title) = vbYes) Then 
    Shell.ControlPanelItem "Desk.cpl"
End If
' 叫用【執行】對話盒
If (MsgBox("開啟【執行】對話盒?", _
           vbYesNo + vbQuestion, Title) = vbYes) Then
    Shell.FileRun
End If
' 叫用【搜尋檔案】對話盒
If (MsgBox("開啟【搜尋所有檔案】對話盒?", _
           vbYesNo + vbQuestion, Title) = vbYes) Then
    Shell.FindFiles
End If
' 叫用【搜尋電腦】對話盒
If (MsgBox("開啟【搜尋電腦】對話盒?", _
           vbYesNo + vbQuestion, Title) = vbYes) Then
    Shell.FindComputer
End If
' 叫用【日期/時間】內容對話盒
If (MsgBox("改變日期/時間?", _
           vbYesNo + vbQuestion, Title) = vbYes) Then
    Shell.SetTime
End If
' 呼叫Suspend方法
If (MsgBox("暫停Windows?", _
           vbYesNo + vbQuestion, Title) = vbYes) Then
    Shell.Suspend
End If
' 叫用【關機】對話盒
If (MsgBox("開啟【Windows關機】對話盒?", _
           vbYesNo + vbQuestion, Title) = vbYes) Then
    Shell.ShutdownWindows
End If
'*** 程式結束
呼叫撥號網路連線
 

您可以使用WSH Script來開始一個撥號網路(Dial-Up Networking, DUN)連線。WSH並不提供直接存取的物件,所以您必須使用小技巧並使用Shell物件的Run方法來呼叫DUN連線。您必須再次藉由使用下面的Windows 95或Windows 98命令來執行RunDll32.exe:
%WINDIR%\RunDll32.exe rnaui.dll,RnaDial名稱
%WINDIR% 是Windows資料夾的佔位符號。佔位符號的名稱代表的是您的DUN資料夾(比方說CS3 Connection)所需的項目。您可以藉由使用 執行 對話盒來檢查此命令(從 開始 功能表中選擇 執行 )。程式14-21中的VBScript程式藉由使用CompuServe(某ISP名稱)連線來連接DUN。
 程式14-21 DUN.vbs
'************************************************
' 檔案:  DUN.vbs (WSH sample in VBScript) 
' 作者:  (c) G. Born
'
' 叫用撥號網路(DUN)
'************************************************
Option Explicit
Dim wsh
Set wsh = WScript.CreateObject("WScript.Shell")
wsh.Run "%WINDIR%\RunDll32.exe rnaui.dll,RnaDial CS3 Connection", _
        1, True
WScript.Echo "就緒!"
'*** 程式結束

注意
如果您在Windows NT中使用DUN,那麼要叫用連線的命令會有點不同。您可以建立DUN項目的捷徑然後使用命令「obj.Run "Rasphone.exe -t xxx", 1, True」(其中xxx指的是DUN項目捷徑檔案的名稱)。

為了更能控制Windows NT中DUN或 撥號網路監視器 (舉例來說,可以撥電話號碼),您可使用提供存取遠端存取服務(Remote Access Service,RAS)或Winsock/TCP/IP之物件和方法的ActiveX控制項。表14-3列出了一些您可以從哪裡下載這樣的ActiveX控制項和範例的網站。
 表14-3 提供存取RAS和DUN之ActiveX控制項的網站
網站說明
 http://www.catalyst.com Catalyst Development Corporation網站。提供給Windows Sockets程式設計與有關TCP/IP程式設計資訊之ActiveX控制項的「SocketTools」工具。
 http://www.voidpointer.com Voidpointer, LLC網站。提供從Script中自動化網際網路相關工作(例如FTP和E-mail)的工具「Script Driven Internet(SDI32)」。
 http://cwashington.netreach.net C. Washington的下載專區網站。包含存取RAS和DUN的ActiveX控制項與範例。
 http://factory.glazier.co.nz Facory Software Components網站。包含有用的ActiveX控制項。
 http://www.mvps.org/ccrp/ Common Controls Replacement Project網站。