[OEM Install]
DisplayWelcomeDlg=YES
DisplayEULA=NO
DisplayTypeOfInstallDlg=NO
DisplaySelectDestDirDlg=YES
DisplayCustomDlg=NO
DisplayUserInfoDlg=NO
DisplayConfirmRegDlg=NO
DisplayStartCopyDlg=NO
DisplayFinishDlg=NO
DisplayFinalMessage=YES
DisplayRebootDlg=YES
ProgGroupName=
DefaultDestDir=
UserName=
UserCompanyName=
UserSerialNumber=
假設我們要對這個檔案做兩件事情:我們要將 DisplayWelcomeDlg 變更為 NO,且要將 UserName 設定為 Ken Myer。理想的狀況是,我們撰寫一個指令碼簡單搜尋 DisplayWelcomeDlg 的檔案、然後將指派的值變更為 NO、搜尋 UserName 屬性、將值設定為 Ken Myer,然後再儲存變更。令人遺憾的是,FileSystemObject (用來讀取並修改文字檔的技術) 並沒有這些功能。所以,我們必須以強迫方式編輯 .INI 檔。也許此時您還是不太瞭解,但希望在閱讀完這個專欄後,您就會瞭解我們所說的意思。
我們將示範一個完整的指令碼,並解釋它的作用:
Const ForReading = 1
Const ForWriting = 2
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFSO.OpenTextFile("sample.ini", ForReading)
Do Until objTextFile.AtEndOfStream
strNextLine = objTextFile.Readline
intLineFinder = InStr(strNextLine, "DisplayWelcomeDlg")
If intLineFinder <> 0 Then
strNextLine = "DisplayWelcomeDlg=NO"
End If
intLineFinder = InStr(strNextLine, "UserName")
If intLineFinder <> 0 Then
strNextLine = "UserName=Ken Myer"
End If
strNewFile = strNewFile & strNextLine & vbCrLf
Loop
objTextFile.Close
Set objTextFile = objFSO.OpenTextFile("sample.ini", ForWriting)
objTextFile.WriteLine strNewFile
objTextFile.Close
先定義兩個常數:ForReading 及 ForWriting。在讀取及寫入 .INI 檔時需要這兩個常數。請注意,沒有名為 ForEditing 的常數;原因是 FileSystemObject 不允許您同時讀取及寫入一個檔案。我們反而是要開啟檔案並讀取,然後關閉檔案,再重新開啟來寫入。此時,我們才能儲存變更。就像我們說的,它不是一項最聰明的系統,但是它就是可以用。
定義完兩個常數後,開啟 .INI 檔 (sample.ini) 讀取。接下來,我們設定一個 Do 迴圈,逐行讀取檔案,直到沒有內容可讀取為止 (當 AtEdnOfStream 屬性為 TRUE)。使用 Readline 方法開始讀取檔案的第一行,然後將那行儲存在 strNextLine 變數中。
現在開始變得有趣了。如稍早所說,FileSystemObject 不允許您搜尋檔案;因此,我們必須逐行讀取檔案,然後分別檢查每一行是不是您要的那行。下面的這行程式碼就是在作這個工作:
intLineFinder = InStr(strNextLine, "DisplayWelcomeDlg")
這個程式碼使用 InStr 方法來查看是否可在 strNextLine 變數中找到 DisplayWelcomeDlg 字串 (請記住,這個變數包含我們剛讀取的 .INI 行)。InStr 的作用是會報告找到目標字串所在的字元位置。例如,假設 strNextLine 等於下列:
xxxxxDisplayWelcomeDlgxxxxx
您可以看見,這個指令碼看起來比較短且清楚,也少了很多雙引號。那為什麼我們不建議您在 XP 或 Windows 2003 上使用這個指令碼?如果您想這麼作是可以的。不過,使用 Shell 物件擷取磁碟配額資訊有兩項限制。第一,Shell 物件指令碼只可針對本機電腦執行;和 WMI 指令碼不同的是,您無法連接到遠端機器並傳回磁碟配額資訊。
第二,您一次只能擷取一台磁碟機的配額資訊。使用 WMI,您可以傳回包含電腦上所有磁碟機之磁碟配額資訊的集合。使用 Shell 物件,您將必須撰寫程式碼取得磁碟機 C: 的資料,然後撰寫程式碼取得磁碟機 D: 的資料,然後再寫程式碼取得磁碟機 E: 的資料等等。
intLineFinder = InStr(strNextLine, "DisplayUserInfoDlg")
您看懂了嗎?現在查看 .INI 檔的第一行,但那不是我們要的。那是要跳過,然後繼續嗎?不,不要跳過。我們要使用這行程式碼:
strNewFile = strNewFile & strNextLine & vbCrLf
這個程式碼會在記憶體中建立全新的 .INI 檔,並將新檔案儲存在 strNewFile 變數中。第一次執行迴圈時,strNewFile 會包含目前在 strNewFile (第一次執行時沒有任何內容) 中的所有內容、「加上」在 strNextLine 變數中的所有內容 ([OEM Install]),再「加上」歸位換行 (vbCrLf)。換句話說,重覆一次之後,strNewFile 看起來會像這樣:
[OEM Install]
很有趣,對吧?
現在,我們進行迴圈然後讀取文字檔的第二行 (DisplayWelcomeDlg=YES)。猜猜看會如何?這次 InStr 找到目標字串,而 intLineFinder 變數會等於 1 (因為 DisplayWelcomeDlg 在第一個字元位置開始)。因為 intLineFinder 不等於 0,所以現在進入第一個 If-Then 區塊。在區塊中,只要變更 strNewLine 的值:
strNextLine = "DisplayWelcomeDlg=NO"
現在,變數中沒有從 .INI 檔讀入的文字;它現在包含了修改過的文字:
DisplayWelcomeDlg=NO
換句話說,我們並沒有真正編輯 DisplayWelcomeDlg 屬性的值。我們只是丟棄舊行,然後用全新的一行取代。不過,最後的結果跟我們直接編輯屬性值並沒有不同。
進入到迴圈的尾端時,strNewFile 變數看起來會像這樣:
[OEM Install]
DisplayWelcomeDlg=NO
看到它的功用了嗎?我們會繼續逐行讀完 .INI 檔,同時逐行地建立 strNewFile 變數。在指令碼完成前,strNewFile 會包含此項資訊:
[OEM Install]
DisplayWelcomeDlg=NO
DisplayEULA=NO
DisplayTypeOfInstallDlg=NO
DisplaySelectDestDirDlg=YES
DisplayCustomDlg=NO
DisplayUserInfoDlg=NO
DisplayConfirmRegDlg=NO
DisplayStartCopyDlg=NO
DisplayFinishDlg=NO
DisplayFinalMessage=YES
DisplayRebootDlg=YES
ProgGroupName=
DefaultDestDir=
UserName=Ken Myer
UserCompanyName=
UserSerialNumber=
沒錯,這和我們在修改的 .INI 檔中想要的資訊完全相同。
我們已經在往目標前進了。接下來關閉 sample.ini 檔,然後馬上重新開啟「寫入」(不是很高明的方法,但必須這麼做)。然後使用下列這行程式碼將 sample.ini 中的現有文字取代為儲存在 strNewFile 變數中的資訊:
objTextFile.WriteLine strNewFile
再次關閉檔案時,就會儲存資料,這就順利修改了 .INI 檔。
我們可不會說這是最好程式碼了;因為它不是。有些 .INI 檔可能無法使用這個功能。但是說實話,這可能是您能做到的最好狀況了,至少有工具內建在作業系統中。 |