◎VBS腳本運行庫手冊之二 ——管理文件夾

 

※管理文件夾

磁盤的屬性比如磁盤的剩餘空間,磁盤的總額提供了一個全局的信息給系統管理員。但是,對於系統管理而言,磁盤的信息雖然是必須的,但是還不夠。知道文件存儲在哪個盤固然重要,但是你也需要知道文件是存儲在哪個文件夾下的。此外許多的系統管理任務都是發生在文件夾級別的,比如複製,移動,刪除和列舉文件夾的內容。

FSO 可以返回一個磁盤上文件夾的全部信息。此外,FSO 提供了一系列的方法來完成諸如:複製、移動、刪除文件夾的操作。

 

 

   如何綁定指定的文件夾

在微軟的調用文件中,文件夾是 COM

對象。這就是說在你訪問一個單獨的文件夾的屬性時,你必須去創建一個文件夾的對象reference,這個過程叫做綁定。你可以用FSOGetObject的方法來綁定到一個文件夾。

當用 GetFolder 的時候,你必須:路徑既可以寫成本地路徑也可以寫成 UNC 路徑(例如://accounting/receivables)。但是通配符不能出現在路徑當中。此外,你不可以創建一個單獨的對象 reference

來同時綁定到多個文件夾。例如,如下的腳本代碼會產生一個錯誤:

objFSO.GetFolder("C:/FSO", "C:/Scripts")

如果你想針對多個文件夾同時工作,你要麼用 WMI 或者用針對每個文件夾創建單獨的對象reference

在設置的時候 Set 這個關鍵詞是必須的,因爲你要標識這個對象 reference 變量。

例如下面的腳本綁定文件夾 C:/FSO

1  Set objFSO = CreateObject("Scripting.FileSystemObject")

2  Set objFolder = objFSO.GetFolder("C:/FSO")

雖然通配符是不允許的,但是你可以用點來關聯到當前的文件夾(.),你可以用點點(..)來綁定到父文件夾,用 / 

綁定到根文件夾。例如如下代碼語句綁定到當前的文件夾:

Set objFolder = objFSO.GetFolder(".")

 

 

※檢驗文件夾是否存在

許多的文件夾的操作包括複製、移動、刪除需要特定的文件夾存在纔可以對其進行操作。畢竟,腳本不能複製、移動、刪除這些不存在的文件夾,如果一個腳本嘗試去對一個不存在的文件夾執行類似的操作,那麼會報錯“path not found”。爲了避免這樣的問題發生,你可以用 FolderExists 方法來在你綁定一個文件夾之前檢查文件夾是否存在。FolderExists用一個簡單的參數(文件夾路徑)來返回一個 Boolean 值,如果文件夾存在,返回的值爲 True,否則返回的值爲 False

例如,下例中列出的腳本,FolderExists 方法來檢查文件夾 C:/FSO 是否存在。如果存在,腳本用 GetFolder 方法來綁定文件夾。如果不存在,腳本就彈出一個 message box 說:Folder does not exist.

1   Set objFSO = CreateObject("Scripting.FileSystemObject")

2   If objFSO.FolderExists("C:/FSO") Then

3   Set objFolder = objFSO.GetFolder("C:/FSO")

4   Wscript.Echo "Folder binding complete."

5   Else

6   Wscript.Echo "Folder does not exist?"

7   End If

 

 

※如何建立文件夾

你不可能永遠都使用你現有的文件系統結構,從來不去更改你的文件系統結構。而事實上,文件系統是動態的,因爲需要變動,現存的文件夾可能被刪除,新的文件夾可能被創建。例如,你的單位在

file servers 上給用戶提供空間,你需要在每個新用戶來的時候創建一個新的文件夾給他。

FSO給腳本編寫者提供了這樣的能力,可以讓你通過腳本來創建文件夾。例如在上例中腳本檢查特定的文件夾是否存在,如果存在,腳本用 GetFolder 的的方法來綁定到這個特定的文件夾,如果不存在,腳本彈出一個消息框。雖然這個方法避免了腳本的失敗,但是你或許更希望在文件夾不存在的時候來創建一個文件夾,而不是簡單的報告說文件夾不存在。爲了做到這點,首先創建一個 FSO 對象實例,然後用CreateFolder 方法,將文件夾的完成路徑作爲參數,例如,下面腳本用這個方法來創建一個新的文件夾 C:/FSO

1   Set objFSO = CreateObject("Scripting.FileSystemObject")

2   Set objFolder = objFSO.CreateFolder("C:/FSO")

如果文件夾存在,那麼會報錯說”file exists”。基於此,你需要在創建文件夾的之前檢查文件對象是否存在。

NoteFSO 只能在本地創建文件夾。如果你想在遠程的計算機上創建文件夾,你需要用到     wshcontroller 對象。你可以在本地創建文件夾然後用 WMI 來將文件夾移動到遠程的計算     機上。(這個文件夾只能先創建再用WMI 移動,因爲 WMI 不支持創建文件夾的方法。)

 

 

  刪除文件夾

當你要刪除文件夾時,例如你用文件服務器存儲每一個員工的數據,當這個員工離開單位時,他的文件夾將被刪除。這保證了文件服務器上的磁盤空間,同樣,你或許用一個腳本來創建一個文件夾來存儲臨時文件,當腳本執行完畢的時候,你會刪除這個臨時的文件。DeleteFolder方法使你可以刪除文件夾和文件夾下的所有文件。DeleteFolder需要一個單獨的參數:文件夾的完全路徑。例如下面腳本用來刪除C:/FSO 和其它所有的東西。

1  Set objFSO = CreateObject("Scripting.FileSystemObject")

2  objFSO.DeleteFolder("C:/FSO")

這個方法會立即刪除所有的文件,它不會讓你確認是否需要刪除就將其扔到垃圾筒。

 

 

※使用通配符(Wildcards)刪除文件夾

腳本的最大的一個優點就是作爲一個管理工具,腳本操作可以同時刪除許 多個項目。例如你可以用腳本的一個單獨的操作就可以刪除所有的文件和文件夾,而不用一個一個去刪除了。

 

FSO 允許你用通配符來刪除一些特定的文件。例如你希望刪除某文件夾下所有以 s 開頭的文件夾,這可以用下面的命令來完成。當用類似這樣的文件夾結構來運行這個的時候,那麼文件夾subfolder1,subfolder2,scripts都會被刪除。

objFSO.DeleteFolder("C:/FSO/S*")

下面這個腳本用來刪除以 su 開頭的文件夾,就是說 subfolder1,subfolder2 會被刪除。

objFSO.DeleteFolder("C:/FSO/Su*")

通配符只能放在文件路徑的最末尾。

例如如下代碼將通配符放在路徑的中間,會報錯:path not found

objFSO.DeleteFolder("C:/*/Subfolder1")

 

 

※複製文件夾及文件夾下的內容

複製文件夾和文件夾當中所有數據能力的對於系統管理任務來說非常重要。有時你需要複製文件夾來創建備份,在計算機 A 和計算機 B 上有同樣的文件夾,如果計算機 B 意外的down掉之後,你就不怕數據丟失了。在其它的時候,你或許希望將含有特定文件的文件夾複製到很多臺計算機上。用腳本來向各個計算機複製這個文件夾比手工複製高效的多。

1CopyFolder 方法允許你複製一個文件夾到另外一個地方。當不用通配符的時候,這個CopyFolder 的方法和命令 Xcopy /E 命令一樣:它拷貝所有的文件和子文件夾,包括空的文件夾。這個命令需要兩個參數:源文件夾->這個文件夾可以被確定爲本地路徑(C:/Script)或者爲 UNC 路徑(//helpdesk/scripts)。目標文件夾->這個文件夾也可以是本地文件夾和 UNC路徑。如果目標文件夾不存在,那麼將自動創建一個文件夾。此外這個方法有個可選的參數:Overwrite,當這個參數存在時,默認的情況下腳本會覆蓋已經存在的目標文件夾。

 

NoteCopyFolder 方法會在遇到錯誤時停止,即使這個腳本中包含有 On Error Resume Next語句。例如你用腳本用來拷貝 100 的子文件夾,當成功拷貝三個之後,遇到一個錯誤。這時腳本會中止,它不去嘗試剩下的 97 的文件夾。

在下例中用 CopyFolder 的方法來複制文件夾 C:/scripts c:/FSO 並且複寫目標文件夾。注意,這個的結果不是 C:/FSO/Scripts 而是 C:/FSO 下有和 C:/Scripts 有同樣的文件。如果你想更改文件夾叫 C:/FSO/Scripts,你應該將目標文件夾改爲 C:/FSO/Scripts

1   Const OverWriteFiles = True

2   Set objFSO = CreateObject("Scripting.FileSystemObject")

3   objFSO.CopyFolder "C:/Scripts" , "C:/FSO" , OverWriteFiles

Note:因爲這個 CopyFolder 是一個單獨的操作,你沒有辦法來跟蹤它的進程。你只是需要簡單的等待操作的結束。如果你想監視 copy

命令的過程,你應該用 shell 應用程序。

 

 

※使用通配符(Wildcards)複製文件夾

用這個CopyFolder 命令也可以拷貝所有文件夾和子文件夾下的文件。這樣可能導致一個問題,如果只是想拷貝 C:/FSO

下的文件,而不是想拷貝C:/FSO/Subfolder1C:/FSO/Subfolder2C:/FSO/Sbufolder3 下的文件。

可是,不幸的是這裏沒有直接的辦法來不拷貝子文件夾中的文件而只是拷貝父文件夾中的文件,你可以用通配符來限制子文件夾的拷貝。例如如下的腳本代碼只是拷貝以 log

字母開頭的文件夾。但是,你用通配符的時候就只是拷貝那些符合特定要求的文件夾才被拷貝:

objFSO.CopyFolder "C:/Scripts/Log*" , "C:/Archive", True

當上面的腳本代碼執行的時候,C:/Scripts/logs,C:/Scripts/Logfiles 被拷貝了,包括它們的文件和子文件夾中的文件。但是,在

C:/Scripts 的文件沒有被拷貝。當你用 CopyFolder

方法的時候,你不能只是拷貝文件夾中的文件,而不拷貝子文件夾中的蚊子。如果你想只是拷貝文件而不拷貝子文件夾的文件,你可以應用 CopyFile 方法。

 

 

※移動文件夾

當你複製一個文件夾從一個地方到另外一個地方的時候,你以複製結束而告終。有時候這個正是你想要的,但是有的時候,你不需要兩份文件的信息,你或許希望將文件夾從計算機

A 移動到計算機 B,或者從硬盤 C 移動到硬盤

D。移動工作總會移動到特定磁盤的剩餘空間上。例如你或許會週期的將很少訪問的文件夾移動到存檔磁盤中。此外你或許有一個腳本來監視本地計算機的信息,當監視結束的時候,你需要將它上傳到服務器,然後將本地文件刪除,然後本地計算機就開始下一次的監視。

MoveFolder 需要兩個參數:

1Source folder 源文件夾,可以是本地路徑或者是 UNC 路徑。

2Destination folder 目標文件夾,這個文件系也可是本地或者 UNC 路徑。

如果你的目標文件夾不存在,那麼移動是成功的。如果目標文件夾存在,那麼不成功。你不能用這個 MoveFolder 的方法來覆蓋一個文件夾。下例腳本中,移動本地的文件夾 C:/Scripts 到一個共享的文件夾 //helpdesk/management

1   Set objFSO = CreateObject("Scripting.FileSystemObject")

2   objFSO.MoveFolder "C:/Scripts" , "//helpdesk/management"

注意用 MoveFolder

方法當腳本失敗後不能循環操作。例如,假如你的網絡連接在腳本將文件從一個計算機移動到另外一個計算機完成前失敗了,那麼很有可能你一些文件在計算機 A 上,另外一些文件在計算機 B 上,也有可能在移動的過程中丟失一些文件。因爲這個 MoveFolder 的方法無法讓腳本恢復到以前狀態。

因爲如此,你或許需要兩個方法來完成文件在網絡中的移動:CopyFolder DeleteFolder。你可以用 CopyFolder 來將文件從計算機 A 移動到計算機 B。當複製的操作結束之後,你用DeleteFolder 來刪除計算機 A 上的文件,當複製操作失敗的時候,你可以確保你的文件還在你的計算機上。

 

 

※重命名文件夾

FSO中沒有提供RenameFolder 方法重新命名文件夾。但是可以用

MoveFolder方法來將文件夾移動到相對同樣的位置,例如假如有文件夾路徑如下:

C:/Scripts/PerformanceMonitoring/Servers/Domain Controllers/Current Logs

如果你用 Windows 瀏覽器來更改文件夾的名字,那麼文件夾還是它本身

C:/Scripts/PerformanceMonitoring/Servers/Domain Controllers/Archived Logs

MoveFolder 的方法可以讓你完成同樣任務,你將

C:/Scripts/PerformanceMonitoring/Servers/Domain Controllers/Current Logs作爲源路徑,將 C:/Scripts/PerformanceMonitoring/Servers/Domain Controllers/Archived Logs作爲目標路徑。這樣的結果和在 windows 瀏覽器中更改文件夾的名字效果是樣的。

例如,下例中的腳本將文件夾C:/FSO/Samples更改爲C:/FSO/Scripts在腳本運行之前,Sample C:/Scripts的文件夾,在腳本運行之後,就是C:/FSO的子文件夾了。此外Scripts FSO 下的)含有原來 Sample

所有的文件和子文件。

1   Set objFSO = CreateObject("Scripting.FileSystemObject")

2   objFSO.MoveFolder "C:/FSO/Samples" , "C:/FSO/Scripts"

 

 

※獲得文件夾屬性

因爲文件夾是一個 COM 對象,它們的屬性可以被獲得和列舉出來,爲了列舉詳細的文件夾信息,你可以用文件夾對象,它是 FSO

的組件之一。文件夾對象的屬性列舉在了下表中。

Attributes             關於文件夾的屬性信息。

DateCreated          文件夾創建的日期

DateLastAccessed           用戶最後訪問這個文件夾的日期

DateLastModified     用戶最後更改文件夾屬性的日期

Drive               磁盤信息包括拖尾符號(比如,C:)標識文件夾所在的磁盤

Files                存儲在這個文件夾中所有文件的信息。

IsRootFolder           Boolean 值來表明這個文件夾是否是根文件夾

Name              文件夾的名字但不包括路徑信息

ParentFolder           文件夾存放的父文件夾的名字

Property                Description

Path                         文件夾的路徑

ShortName             MS-DOS 類型的文件夾的名字,遵循 8.3 的命名規則。

ShortPath               MS-DOS 類型的文件夾的名字,遵循 8.3 的命名規則。

Size                 文件夾的大小,單位是 bytes,包含子文件和子文件夾的大小在內。

 

SubFolders              第一層的子文件夾。在 Subfolders 中的子文件夾不在此列中。

 

Type           對於文件夾的描述

※列舉文件夾的屬性

爲了得到一個文件夾的屬性,一個腳本必須:

1.創建一個 FSO 實例

2. GetFolder 的方法綁定特定文件夾

3. Echo 的方法顯示屬性。

當你對一個文件夾的屬性進行操作的時候,注意文件的屬性和子文件夾的屬性是以集合的形式返回的,不是單獨返回一個的。此外Attributes 屬性返回一個屬性值。

1   Set objFSO = CreateObject("Scripting.FileSystemObject")

2   Set objFolder = objFSO.GetFolder("C:/FSO")

3   Wscript.Echo "Date created: " & objFolder.DateCreated

4   Wscript.Echo "Date last accessed: " & objFolder.DateLastAccessed

5   Wscript.Echo "Date last modified: " & objFolder.DateLastModified

6   Wscript.Echo "Drive: " & objFolder.Drive

7   Wscript.Echo "Is root folder: " & objFolder.IsRootFolder

8   Wscript.Echo "Name: " & objFolder.Name

9   Wscript.Echo "Parent folder: " & objFolder.ParentFolder

10   Wscript.Echo "Path: " & objFolder.Path

11    Wscript.Echo "Short name: " & objFolder.ShortName

12   Wscript.Echo "Short path: " & objFolder.ShortPath

13   Wscript.Echo "Size: " & objFolder.Size

14   Wscript.Echo "Type: " & objFolder.Type

※管理文件夾的屬性

文件系統支持屬性的定義。就是文件夾中和文件夾名字和文件夾大小無關的信息。例如如果你在 Windows 瀏覽器中右擊某個數據夾的時候,點 Properties 你就可以訪問文件夾的屬性了。

FSO 可以返回幾個關於文件夾信息的重要屬性。這些屬性和相應的值,列舉在下表中:

Hidden        2            隱藏,就是在 Windows 瀏覽器中不可見

System        4        表示它是一個系統文件夾。建議不要更改系統文件夾的內容。

Directory      16          應用到所有的文件夾的標準值。所有可以被 FSO 訪問的文件

夾讀有這個值,最小位 16

Archive        32             存盤的屬性用在備份程序中,用來決定文件是否需要備份。

如果這個值 enabling 表示文件夾在下一次增量備份中會備份。如果

disabling 表示不在下一次增量備份中備份

Compressed       2048     表明這個文件夾是否是壓縮的

雖然這些看起來很簡單,但是從

FSO返回的數據看起來會讓你感到很迷惑。例如,你返回一個文件夾的屬性值,你或許會看到20,但是這個值並不是像上面一樣的標準值。此外,你可能會獲得一個單獨的值,雖然這個文件夾有說有的屬性。這種情況是,腳本並不是返回如

2,4,16,32,2048 這樣的值,而只是返回一個 2102。這是因爲這些值是以位圖的形式顯示的。

Note:對於屬性值,它返回和存儲的數據是以位圖的形式的。對於位圖你應該不會奇怪,比如後綴名爲.bmp 的圖形文件

位圖看起來就是一系列的開關。如果特定的開關是關閉的,那麼這個開關的值就是0,如果是開啓的,比如文件夾對象吧,它就具有上表中所列出的值。而位圖的值就是這些開關的值的總和。如果你用腳本查詢這個文件夾的屬性,腳本就返回一個值爲 16.

與其相反,如果有三個開關是開啓的:隱藏(值是2,Directory(值是16),壓縮(值是 2048).那麼這個位圖的值應該是 2+16+2048,或者值是 2066。這個也是用腳本查詢的時候返回的值。位圖被設計成只是有一種辦法來獲取特定的值。得到值 2066 的方法只有一個就是壓縮和隱藏。你不可能通過別的數學方法來算得這樣的值。

這個設計可以返回值並且決定哪個開關沒有開哪個沒有開。這個可以允許你來判斷文件夾的哪個屬性設定了。如果你得到了這個 2066

的值,那麼它的屬性就是隱藏壓縮的文件夾。幸運的是,你不必去作任何單獨的數字運算,你可以用邏輯與 AND 操作來決定哪個開關是否是on 還是 off。例如如下代碼查詢文件夾是否是隱藏的,如果是回顯一個信息框: Hidden folder

If objFolder.Attributes AND 2 Then

   Wscript.Echo "Hidden folder."

End If

或者:  If objFolder.Attributes AND 16 Then

下列腳本先綁定文件夾 C:/FSO,然後回顯文件夾屬性:

(譯者注:這個其實是挨個匹配的,所以你要是測試了兩個屬性,它都會顯示出來的。)

1    Set objFSO = CreateObject("Scripting.FileSystemObject")

2    Set objFolder = objFSO.GetFolder("C:/FSO")

3    If objFolder.Attributes AND 2 Then

4    Wscript.Echo "Hidden folder."

5    End If

6    If objFolder.Attributes AND 4 Then

7    Wscript.Echo "System folder."

8    End If

9    If objFolder.Attributes AND 16 Then

10   Wscript.Echo "Folder."

11   End If

12   If objFolder.Attributes AND 32 Then

13   Wscript.Echo "Archive bit set."

14   End If

15   If objFolder.Attributes AND 2048 Then

16   Wscript.Echo "Compressed folder."

17   End If

※改變文件夾屬性

文件夾的每個屬性可以看成一個個開關,如果關於隱藏的開關是ON 的,那麼這個文件夾就是隱藏的,如果這個開關是 OFF

的,那麼這個文件夾就不是隱藏的,你可以選擇打開或者關掉它們,對於文件夾的屬性也是如此:對於其它的開關,你可以將屬性設置爲開或者設置爲關,你可以用腳本來控制這些開關的,最簡單的控制屬性開關的辦法是用如下的程序:

 

1. GetFolder 的方法來綁定到一個文件夾。

2. 檢查你需要更改的值。例如你想隱藏一個文件夾,看這個文件夾是否是已經隱藏了

3. 如果這個文件夾是隱藏的,用 XOR 操作來將開關轉換成非隱藏的。如果這個文件夾不是隱藏的,注意不要用

XOR,如果你用了,開關會被觸發,文件夾會中止於隱藏。例如,下列腳本用 AND 來判斷文件夾 C:/FSO 的隱藏屬性開關是否開着。如果它是開的,腳本用 XOR

操作來將開關關閉來顯示文件夾。

1      Set objFSO = CreateObject("Scripting.FileSystemObject")

2    Set objFolder = objFSO.GetFolder("C:/FSO")

3    If objFolder.Attributes AND 2 Then

4     objFolder.Attributes = objFolder.Attributes XOR 2

5    End If

除非很少的一些情況以外,文件夾用來作爲單獨存放文件的地方。有時候,這些文件夾是系統需要的。例如操作系統希望在特定的文件夾內找到特定的文件。在其它的一些時候,文件夾是系統管理員管理計算機的一種工具也是用戶管理文件的工具。系統管理員可能希望將腳本放在叫做Scripts

的文件夾,將一些 trouble-shooting 的工具放在叫做 Diagnostic Tools 的文件夾。用戶或許將他們預算信息放在叫做 Budgets

的文件夾,而將薪水的信息放在叫做 Timecards

的文件夾。當然,文件夾一般是限制使用的,你必須知道這個文件夾是存放的是什麼文件。系統管理員需要知道是不是有個特定的腳本存在 C:/Scripts 文件夾中,用戶需要知道是不是有個特定的窗體存在C:/Budgets 的文件夾中。文件夾對象包含了一些屬性可用來返回存儲在文件夾內文件集合的信息,爲了得到這些信息,你的腳本必須:

1. 創建一個 FSO 對象實例。

2. GetFolder 的方法來綁定到一個適當的文件夾。

3. 設置一個對象 reference 來指向文件夾的屬性

4. For Each 循環來列舉出所有的文件和他們的屬性。腳本不必去綁定到每一個單獨的文件去獲得文件的信息。

在下列腳本中返回在文件夾 C:/FSO 下所有文件的信息並且回顯他們的名字和大小:

1  Set objFSO = CreateObject("Scripting.FileSystemObject")

2    Set objFolder = objFSO.GetFolder("C:/FSO")

3    Set colFiles = objFolder.Files

4    For Each objFile in colFiles

5     Wscript.Echo objFile.Name, objFile.Size

6   Next

對於大多數返回的集合來說,你不能控制輸出信息的順序。就是說你不能將輸出的格式定義爲按照名字,按照大小或者其它別的原則。如果你想讓輸出的東西按照特定的格式,你就必須將他們拷貝到數組,目錄或者一個 disconnected recordset 然後將他們分類排列。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章