Lesson13 ファイルシステムにアクセスする
FileSystemObjectのメソッド -FileSystemObjectオブジェクト-
前回まではWScriptオブジェクトと、そこから派生するオブジェクトを解説してきましたが、今回からはファイルシステムを操作する、FileSystemObjectオブジェクトの解説に入りたいと思います。
FileSystemObjectオブジェクトは、スクリプティングランタイムが提供する、ActiveXオブジェクトの一つですので、WSHから利用することができるわけです。利用方法は、
Set Fs=WScript.CreateObject("Scripting.FileSystemObject")
のようにします。これでFsというオブジェクト変数に、FileSystemObjectオブジェクトが代入されます。
FileSystemObjectオブジェクトのメソッド・プロパティは、
ファイル・フォルダ・ドライブの情報を取得するもの
BuildPath メソッド | パスに新しくフォルダ名・ファイル名を付け足す |
DriveExists メソッド | ドライブが存在するかどうか |
FileExists メソッド | ファイルが存在するかどうか |
FolderExists メソッド | フォルダが存在するかどうか |
GetAbsolutePathName メソッド | フルパスを返す |
GetBaseName メソッド | 拡張子を除いたファイルの名前を返す |
GetDriveName メソッド | ファイルの存在するドライブ名を返す |
GetExtensionName メソッド | 拡張子名を返す |
GetFileName メソッド | ファイル名を返す |
GetParentFolderName メソッド | 親フォルダ名を返す |
GetTempName メソッド | テンポラリなファイル名(.tmp)を生成 |
ファイル・フォルダを操作(コピー・削除など)をおこなうもの
CopyFile メソッド | ファイルをコピー |
CopyFolder メソッド | フォルダをコピー |
CreateFolder メソッド | フォルダを作成 |
CreateTextFile メソッド | テキストファイル作成 |
DeleteFile メソッド | ファイルを消去 |
DeleteFolder メソッド | フォルダを消去 |
MoveFile メソッド | ファイルを移動 |
MoveFolder メソッド | フォルダを移動 |
ファイル・フォルダ・ドライブをオブジェクトとして取得するもの
CreateFolder メソッド | フォルダを作成し、Folderオブジェクトを返す |
GetDrive メソッド | Driveオブジェクトを返す |
GetFile メソッド | Fileオブジェクトを返す |
GetFolder メソッド | Folderオブジェクトを返す |
GetSpecialFolder メソッド | 特別なフォルダのFolderオブジェクトを返す |
Drives プロパティ | Drivesコレクションを返す |
テキストファイルをオブジェクトとして取得するもの
CreateTextFile メソッド | テキストファイルを作成し、TextStremオブジェクトを返す |
OpenTextFile メソッド | TextStremオブジェクトを返す |
の4つに大別できます。このLesson13では1.と2.に属するメソッドを中心に解説します。なお、このLessonは、VBSランゲージリファレンスの「スクリプティングランタイムリファレンス」とともにご覧ください。
まずはファイル情報を取得する例から見ていきましょう。
Dim Fs,info Set Fs = WScript.CreateObject("Scripting.FileSystemObject") Const filename="C:\Windows\tips.txt" 'ファイル名を決めます。 If Fs.FileExists(filename)=False Then 'FileExistsメソッド。引数が存在するファイル名ならTrue、存在しないとFalseを返す。 MsgBox filename & "というファイルは存在しません。" WScript.Quit End If info="ファイル名=" & Fs.GetFileName(filename) & vbCrLf & _ "フルパス=" & Fs.GetAbsolutePathName(filename) & vbCrLf & _ "親フォルダ名=" & Fs.GetParentFolderName(filename) & vbCrLf & _ "ドライブ名=" & Fs.GetDriveName(filename) & vbCrLf & _ "拡張子=" & Fs.GetExtensionName(filename) & vbCrLf & _ "拡張子を除いた名前=" & Fs.GetBaseName(filename) MsgBox info
このスクリプトは、FileSystemObjectオブジェクトでわかるファイルの情報を列挙するものです。この例では、WindowsフォルダにあるTips.txtというファイルを使っています。
前半部分で、FileExistsメソッドを使って、ファイルが存在しているかどうかをチェックしています。ファイルが存在しない場合はFalseを返すので、スクリプトは終了します。
後半部分で、Getの名が付く各メソッド(GetAbsolutePathName
メソッド、GetBaseName メソッド、GetDriveName
メソッド、GetExtensionName メソッド、GetFileName
メソッド、GetParentFolderName メソッド)を使って、ファイルの情報を取得し、最後にそれを表示しています。
ちなみに _ (アンダースコア)は、コードを複数行に分割するときの記号です。
ところで、スクリプティングランタイムでは、ファイル名を指定するときはこのようにフルパスで指定するのが原則です。ただ、実行したスクリプトファイル(.vbs)が存在するフォルダにあるファイルについては、フォルダ名を省略することもできます。たとえばC:\Windows
に上記のスクリプトファイルを作成し、Const
filename="tips.txt"のようにファイル名だけ指定しても動作します。
ただし注意しなければならないのは、ファイル情報Get系のメソッドは、引数のファイルの有無に関わらず、引数の文字列を変換するだけであることです。つまり、"tips.txt"を指定した場合、この文字列にはパスが書かれていないのでGetParentFolderNameメソッドなどでは値を返しません。
また同じ理由で、FileExistsメソッドによる判断ルーチンを削った場合、存在しないパスを指定しても何らかの値が返ってきます。いろいろ試してみてください。
次は、ファイルやフォルダを作成する例です。
Dim Fs,folderpath,filepath Set Fs = WScript.CreateObject("Scripting.FileSystemObject") Const foldername="C:\Windows" 'フォルダを作成するフォルダを指定 Const newfoldername="新しいフォルダ" '新しく作成するフォルダ名 folderpath=Fs.BuildPath(foldername,newfoldername) '1.新しく作成するフォルダのフルパスを得る If Fs.FolderExists(folderpath) Then '2.もしフォルダが既存なら終了 MsgBox "すでに同名のフォルダが存在しています。" WScript.Quit End If Fs.CreateFolder folderpath '3.フォルダを作成 MsgBox folderpath & "を作成しました。" filepath=Fs.BuildPath(folderpath,Fs.GetTempName) '4.適当な名前のファイル名を得る Fs.CreateTextFile filepath '5.新しく作ったフォルダに、0バイトのテキストファイルを作成 MsgBox filepath & "を作成しました。"
これはWindowsフォルダに新しいフォルダを作成し、その中にサイズ0のテキストファイルを作るスクリプトです。
まず、1.でBuildPathメソッドを使って、C:\Windowsというフォルダの中に「新しいフォルダ」という名前のフォルダを作ったとき、できるフォルダのパスを調べてfolderpathという変数に代入しています。この場合folderpathにはC:\Windows\新しいフォルダ
という文字列が入ります。
ところでこんな面倒なことをしなくても、
folderpath=foldername & "\" & newfoldername
とやればいいのでは?と思われるかもしれませんが、BuildPathメソッドは「適切な位置にパス区切り文字(\)を付加してくれる」という長所があるのでこちらを使うようにしましょう。上のようにしてしまうと、foldernameに \ がついていた場合、\ が余分になってしまいますね。
2.ではFolderExistsメソッドでフォルダの有無をチェックしています。ちなみにドライブの有無を調べるにはDriveExistsメソッドを使えばいいのです。
3.でCreateFolderメソッドを使ってフォルダを作成しています。このとき引数にすでに存在するフォルダを指定するとエラーになってしまうので、2.でそれをチェックしたわけです。
4.ではGetTempNameメソッドを利用して、ランダムなテンポラリなファイル名(拡張子は.tmp)を取得しています。そしてBuildPathメソッドでそのファイルのフルパスを取得しているわけです。
5.でCreateTextFileメソッドを使って空のファイルを作成しています。CreateTextFileメソッドは、第二引数にTrueを指定すると、もし第一引数のファイル名が既存の場合、上書きするようになります。
次にファイルをコピーする例です。
Dim Fs,WSHShell,source,target,msg Set Fs = WScript.CreateObject("Scripting.FileSystemObject") Set WSHShell = WScript.CreateObject("WScript.Shell") source=Fs.BuildPath(WSHShell.SpecialFolders("Desktop"),"*.lnk") '1.デスクトップにあるショートカットを指定 target=Fs.BuildPath(WSHShell.SpecialFolders("StartMenu"),"デスクトップ\") '2.ショートカットをコピーする、スタートメニュー内のフォルダを指定 msg=MsgBox ("今から" & source & "を" & target & "にコピーします。いいですか?",vbYesNo) If msg=vbNo Then Wscript.Quit '「いいえ」と答えたら終了 If Fs.FolderExists(target)=False Then '3.もしフォルダがなければ作成する Fs.CreateFolder target End If Fs.CopyFile source,target '4.ファイルをコピー
このスクリプトは、デスクトップにあるショートカットをスタートメニューにコピーするスクリプトです。これを実行すると、デスクトップがウィンドウでいっぱいになってもショートカットにはアクセスできるようになります。お、なんか実用的。(バッチファイルでもこれくらいは書けますって?)
1.ではWshShellオブジェクトのWshSpecialFoldersオブジェクトを使って、デスクトップの場所を参照しています。そしてBuildPathメソッドですべてのショートカット(.lnk)を含んだパスをsourceという変数に代入しています。
次に2.ではスタートメニューフォルダの位置を取得し、そこに「デスクトップ」というサブフォルダ名を付加したパスを取得し、targetという変数に代入しています。
フォルダがないと困るので3.で確認しています。
そして4.でCopyFileメソッドを使ってコピーを実行。この場合
Fs.CopyFile "C:\Windows\デスクトップ\*.lnk","C:\Windows\スタート メニュー\デスクトップ\"
という行が実行されたことになります。CopyFileメソッドの第一引数にはコピー元を指定します。上の例のように*(ワイルドカード)を用いて複数のファイルを指定できますが、もちろん単一のファイルも指定できます。
第二引数にはコピー先を指定します。このとき、コピー先にフォルダを指定するときは上のように末尾に
\ をつけなければなりません。コピー元が単一のファイルなら、コピー先にファイル名を指定することも可能です。
CopyFileメソッドの第三引数にFalseを指定すると、コピー先に既存のファイルがあっても上書きしなくなります。省略すると上書きします。ただし、コピー先が読みとり専用属性の場合エラーになります。
さてフォルダをコピー・削除する例も見ておきましょう。
Dim Fs,WSHShell,source,target,msg Set Fs = WScript.CreateObject("Scripting.FileSystemObject") Set WSHShell = WScript.CreateObject("WScript.Shell") source=Fs.BuildPath(WSHShell.SpecialFolders("AppData"),"Microsoft\Outlook Express\*") target= "C:\backup" 'バックアップ先を指定 msg=MsgBox ("今から" & source & "を" & target & "にコピーします。いいですか?",vbYesNo) If msg=vbNo Then Wscript.Quit '「いいえ」と答えたら終了 If Fs.FolderExists(target)=False Then 'もしフォルダがなければ作成する Fs.CreateFolder target Else 'ある場合は、フォルダを削除してから作成する msg=MsgBox (target & "フォルダの内容は削除されます!よろしいですか?",vbYesNo) If msg=vbNo Then Wscript.Quit '「いいえ」と答えたら終了 Fs.DeleteFolder target Fs.CreateFolder target End If Fs.CopyFolder source,Fs.BuildPath(target,"\") 'フォルダをコピー MsgBox "処理が終了しました。"
これはOutlook Express4のデータをバックアップするスクリプトです。(注意:このスクリプトはOE4専用です。OE5では動作しない可能性があります。また、バックアップ先のフォルダは各自変更のこと。)
OutlookExpressのデータは、C:\WINDOWS\Application
Data\Microsoft\Outlook Express以下のフォルダにあります。よってまずApplication
DataフォルダをWshSpecialFoldersオブジェクトにより取得して、BuildPathメソッドでつなげます。
バックアップ先のフォルダが存在する場合は、これをまず削除します。削除するにはDeleteFolderメソッドを用います。DeleteFolderは、第一引数に削除するフォルダのパスを指定します。第二引数にTrueを指定すると、読みとり専用フォルダであっても強制的に削除します。
フォルダをコピーする場合はCopyFolderメソッドを用います。このメソッドは、第一引数のフォルダを、サブフォルダ・ファイル含めて、第二引数で指定したフォルダにコピーするものです。
この場合結局
Fs.CopyFolder "C:\WINDOWS\Application Data\Microsoft\Outlook Express\*","C:\Backup\"
なる行が実行されたことになります。このようにワイルドカードを用いると、サブフォルダを指定することが可能です。(もちろん単一のフォルダも指定できます。その場合末尾には\をつけないようにします。)
まだまだ続きます。次はファイルやフォルダを移動するスクリプトです。
On Error Resume Next Dim Fs,WSHShell,source,target,msg Set Fs = WScript.CreateObject("Scripting.FileSystemObject") Set WSHShell = WScript.CreateObject("WScript.Shell") If WScript.Arguments.Count=0 Then '1.もしコマンドラインオプションが指定されなければ、終了。 MsgBox "フォルダ名を指定して実行してください。" Wscript.Quit End If source=WScript.Arguments(0) '2.sourceには、一つ目のコマンドラインオプションを代入 If Fs.FolderExists(source)=False Then '3.指定したフォルダが存在しなければ、終了。 MsgBox "指定されたフォルダ" & source & "は存在しません。" Wscript.Quit End If target=Fs.GetParentFolderName(source) '4.targetにはsourceの親フォルダを代入 If Fs.FolderExists(target)=False Then '5.親フォルダが存在しない場合は、終了。 MsgBox "このフォルダには親フォルダが存在しません。" Wscript.Quit End If msg=MsgBox (source & "にあるサブフォルダとファイルを、" & target & "に移動します。いいですか?",vbYesNo) If msg=vbNo Then Wscript.Quit '「いいえ」と答えたら終了 Fs.MoveFile Fs.BuildPath(source,"*.*"),Fs.BuildPath(target,"\") '6.ファイルを移動 Fs.MoveFolder Fs.BuildPath(source,"*"),Fs.BuildPath(target,"\") '7.サブフォルダを移動 MsgBox "処理が終了しました。"
このスクリプトは、コマンドラインオプションで指定したフォルダの中身(サブフォルダとファイル)を、そのフォルダの親フォルダの直下に移動するスクリプトです。吸い出しの巻物.vbsという名前を付けてください。
オプションをつけて実行する方法は、一つ前のLesson12で述べました。
まず1.でコマンドラインオプション(以下、オプション)の記述の有無をチェックしています。
2.でsourceという変数に、一つ目のオプションを代入しています。
3.ではsourceが存在するフォルダかどうかチェックしています。
4.ではGetParentFolderNameメソッドで、targetという変数に、sourceの親フォルダを代入しています。
5.で今度はtargetの有無をチェックしています。何故この処理が必要かというと、sourceがルートフォルダ(ドライブ)の場合、その親フォルダは存在しないからです。
6.でMoveFileメソッドを使って、指定されたフォルダの中にあるファイルを、一つ上のディレクトリに移動しています。MoveFileメソッドは、第一引数にファイル名、第二引数に移動先フォルダを指定します。この例だと、たとえばオプションにC:\My Document\My Pictures を指定した場合、
Fs.MoveFile "C:\My Document\My Pictures\*.*","C:\My Document\"
が実行されたことになります。MoveFileメソッドもワイルドカードを利用することができますが、単一ファイルの指定も可能です。
7.では今度はMoveFolderメソッドで、サブフォルダを移動させています。
Fs.MoveFolder "C:\My Document\My Pictures\*","C:\My Document\"
とした場合と同じです。
MoveFileメソッド・MoveFolderメソッドでは、第一引数に指定したファイル・フォルダが存在しない場合や、第二引数に指定したフォルダにすでに同名のファイル・フォルダが存在するとエラーになりますが、この例ではOn Error Resume Nextを用いてそのエラーを無視するようにしています。とはいってもエラーが発生すると、その時点で移動は中止されてしまいますが。
ちなみにこのスクリプトでは、ファイル・フォルダを移動しますが、CopyFile、CopyFolderメソッドを使えば、コピーするように改造できます。
フォルダの右クリックメニューに組み込むと、便利かもしれませんね。
これで最後です。ファイルを削除するスクリプトをどうぞ。
On Error Resume Next Dim Fs,WSHShell,file Set Fs = WScript.CreateObject("Scripting.FileSystemObject") Set WSHShell = WScript.CreateObject("WScript.Shell") file=Fs.BuildPath(WSHShell.SpecialFolders("Recent"),"*.*") 'recentフォルダの場所を取得 msg=MsgBox (file & "を削除します。いいですか?",vbYesNo) If msg=vbNo Then Wscript.Quit '「いいえ」と答えたら終了 Fs.DeleteFile file 'ファイルを削除
これは、「最近使ったファイル」をクリアするスクリプトです。
最近使ったファイルは通常C:\WINDOWS\Recentというフォルダにそのショートカットが作られています。WshSpecialFoldersオブジェクトでは"Recent"を指定するとそのフォルダの場所が取得できます。
ファイルを削除するにはDeleteFileメソッドを使います。DeleteFileメソッドは、第一引数として削除するファイル名を指定します。第二引数にTrueを指定すると、読みとり専用ファイルも削除します。
この例では、
Fs.DeleteFile "C:\WINDOWS\Recent\*.*"
が実行されたことになります。
このLessonでは、FileSystemObjectを使って、ファイル操作する方法について述べました。次回は、このLessonの冒頭で紹介したメソッド・プロパティのうち、3.で挙げたものを使って、フォルダ・ファイル・ドライブの各オブジェクト・コレクションを取得し、それらのオブジェクトが持つプロパティ・メソッドを紹介したいと思います。