FileSystemObjectを利用したWSHからのファイル操作法。今回はフォルダの操作とドライブの操作について解説する。
これまではファイルの操作について説明してきた。次に以下では、フォルダの操作方法について説明しよう。フォルダに対しても、ファイルの処理と同様に、コピー、移動、削除、作成、情報取得ができる。処理方法もファイルに対するものと同様に、FSOオブジェクトを直接利用する方法と、Folderオブジェクトを作成して利用する方法の2種類が提供されている。まずはFSOオブジェクトを使用する方法を述べてから、Folderオブジェクトを使用する方法について述べることにする。
以下はFSOオブジェクトのメソッドのうち、フォルダに関係するものの一覧である。
メソッド | 機能 |
---|---|
CopyFolderメソッド | フォルダをコピーする |
MoveFolderメソッド | フォルダを移動する |
DeleteFolderメソッド | フォルダを削除する |
FolderExistsメソッド | フォルダが存在するかどうかを調べる |
CreateFolderメソッド | フォルダを作成する |
GetFolderメソッド | Folderオブジェクトを返す |
GetSpecialFolderメソッド | 特殊フォルダのFolderオブジェクトを返す |
フォルダのコピーにはCopyFolderメソッドを用いる。CopyFolderメソッドにコピー元のフォルダ名とコピー先のフォルダ名を渡すことで、フォルダをコピーできる。この場合、フォルダに含まれるファイルやサブフォルダもコピーされる。通常、コピー先にすでにフォルダがある場合は既存フォルダ内のファイルが上書きされるが、第3パラメータにFalseを指定することで、ファイルを上書きせずにエラーを発生させることができる。
objFSO.CopyFolder source , destination [, overwrite]
コピー先文字列が「\」で終わる場合には、指定したフォルダの直下に元と同じフォルダ名でフォルダがコピーされる。そうでない場合、指定したフォルダ名でコピー先のフォルダが作成される。例えば、次のコードの1行目では「D:\WSH\Folder2」というフォルダが作成され、2行目では「D:\WSH\Folder2\Folder1」というフォルダが作成される。
1: objFSO.CopyFolder "D:\WSH\Folder1", "D:\WSH\Folder2"
2: objFSO.CopyFolder "D:\WSH\Folder1", "D:\WSH\Folder2\"
コピー元フォルダ名にはワイルドカードを指定することもできる。ただしワイルドカードを指定できるのは最後の「\」記号以降の、実際にコピーを行うフォルダ名のみで、パス部分には指定できない。ワイルドカードを指定した場合には複数のフォルダがコピーされる可能性があるので、コピー先は常に既存フォルダ名であると認識される。ワイルドカードで指定したコピー元フォルダ名に一致するフォルダがなかった場合には、エラーが発生する。
フォルダの移動にはMoveFolderメソッドを用いる。
objFSO.MoveFolder source , destination
CopyFolderメソッドと同じように、コピー先文字列が「\」で終わる場合には、指定したフォルダの直下に元と同じフォルダ名でフォルダがコピーされる。そうでない場合、指定したフォルダ名でコピー先のフォルダが作成される。移動先にすでに同名のフォルダが存在する場合にはエラーが発生する。移動元のフォルダ名の指定には、ワイルドカードを使用できる。
フォルダの削除にはDeleteFolderメソッドを用いる。この際、フォルダ内にファイルやサブフォルダがある場合には、それらも削除される。通常は読み取り専用属性を持つフォルダは削除しないが、第2パラメータにTrueを指定すると読み取り専用属性を持つフォルダも削除できる。削除するフォルダ名にはワイルドカードを利用できる。
objFSO.DeleteFolder folderspec [, force]
FolderExistsメソッドは、フォルダが存在する場合にTrueを、存在しない場合にFalseを返すメソッドである。
objFSO.FolderExists(folderspec)
CreateFolderメソッドは、フォルダを作成するメソッドである。指定したフォルダがすでに存在していた場合や、親フォルダが存在しない場合にはエラーが発生する。CreateFolderメソッドは戻り値として後述するFolderオブジェクトを返す。
CreateFolderメソッドやCreateTextFileメソッドは、親フォルダが存在しないとエラーが発生する。自動的に必要なフォルダを作成するには、以下のようなプロシージャを定義すればよい。
1: Sub CreateFolder2(objFSO, strFolder)
2: strParent = objFSO.GetParentFolderName(strFolder)
3: If Not objFSO.FolderExists(strParent) Then
4: CreateFolder2 objFSO, strParent
5: End If
6: objFSO.CreateFolder(strFolder)
7: End Sub
8:
9: Function CreateTextFile2(objFSO, strFile)
10: strParent = objFSO.GetParentFolderName(strFile)
11: If Not objFSO.FolderExists(strParent) Then
12: CreateFolder2 objFSO, strParent
13: End If
14: Set CreateTextFile2 = objFSO.CreateTextFile(strFile)
15: End Function
16:
17: Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")
18: Set objOutput = CreateTextFile2(objFSO, "D:\WSH\Folder1\Folder2\Test.txt")
19: objOutput.WriteLine Now
GetParentFolderNameメソッドは、フォルダ名やファイル名に対し、その親フォルダの名前を返すメソッドである。CreateFolder2プロシージャでは、親フォルダが存在しなければ、再帰的に親フォルダを作成した後、指定されたフォルダを作成する。CreateTextFile2プロシージャは、親フォルダが存在しなければ親フォルダを作成した後に通常のCreateTextFileを呼び出す。これらの処理により、18行目では、必要に応じてFolder1、Folder2が作成された後、Test.txtが作られる。
WSHでは、特殊フォルダを取得する方法として、WshShellオブジェクトのSpecialFoldersプロパティやExpandEnvironmentStringsメソッドが用意されている(これらの詳細については連載第6回を参照)。しかしFSOオブジェクトのGetSpecialFolderメソッドを使うことでも、Windowsフォルダ、Systemフォルダ、Tempフォルダの3種類の特殊フォルダを取得することができる。
GetSpecialFolderメソッドでは、どの特殊フォルダを取得するかを整数値で指定する。具体的には、Windowsフォルダは0、Systemフォルダは1、Tempフォルダは2を指定する。GetSpecialFolderメソッドは、フォルダ名ではなく、Folderオブジェクトを返す。次の例では、取得したFolderオブジェクトのPathプロパティの値を表示している。
Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")
WScript.Echo objFSO.GetSpecialFolder(0).Path
WScript.Echo objFSO.GetSpecialFolder(1).Path
WScript.Echo objFSO.GetSpecialFolder(2).Path
D:\WSH>cscript specialfolder.vbs
C:\WINDOWS
C:\WINDOWS\system32
C:\DOCUME~1\tomo-k\LOCALS~1\Temp
D:\WSH>
Folderオブジェクトは、フォルダを表すオブジェクトである。このオブジェクトを利用して、フォルダのコピーや移動、削除、フォルダの持つ属性の取得、設定ができるほか、フォルダ内のファイルやサブフォルダを列挙することができる。
Folderオブジェクトを取得するには、FSOオブジェクトのGetFolderメソッド、GetSpecialFolderメソッド、CreateFolderメソッド、FileオブジェクトのParentFolderプロパティ、Folderオブジェクト自身が持つParentFolderプロパティやSubFoldersプロパティ、後述するDriveオブジェクトのRootFolderプロパティを利用する。フォルダ名が分かっている場合には、これらのうちGetFolderメソッドが利用できる。例えば、「D:\WSH」というフォルダを表すFolderオブジェクトを取得するには次のようにする。
Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")
Set objFolder = objFSO.GetFolder("D:\WSH ")
Folderオブジェクトには、以下のメソッド・プロパティがある。
メソッド/プロパティ | 機能 |
---|---|
Copyメソッド | フォルダをコピーする |
Deleteメソッド | フォルダを削除する |
Moveメソッド | フォルダを移動する |
Attributesプロパティ | 属性を取得・設定する |
DateCreatedプロパティ | 作成日時を取得する |
DateLastAccessedプロパティ | 最終アクセス日時を取得する |
DateLastModifiedプロパティ | 最終更新日時を取得する |
Driveプロパティ | フォルダの格納されているドライブを表すDriveオブジェクトを取得する |
Filesプロパティ | フォルダ内のファイルのコレクションを返す |
IsRootFolderプロパティ | ルートフォルダであればTrueを返す |
Nameプロパティ | フォルダの名前を取得・設定する |
ParentFolderプロパティ | 親フォルダを表すFolderオブジェクトを取得する |
Pathプロパティ | フォルダのパスを取得する |
ShortNameプロパティ | MS-DOS形式のフォルダ名を取得する |
ShortPathプロパティ | MS-DOS形式のパスを取得する |
Sizeプロパティ | フォルダの合計サイズを取得する |
SubFoldersプロパティ | サブフォルダのコレクションを返す |
Typeプロパティ | フォルダの種類を取得する |
これらのメソッド/プロパティは、ほとんどがFileオブジェクトと共通のものであり、使い方もFileオブジェクトの場合と違いはない。Fileオブジェクトと異なるプロパティは、Filesプロパティ、SubFoldersプロパティ、IsRootFolderプロパティの3つのみである。ここではこれらFolderオブジェクト特有のプロパティについて解説する。
■Files/SubFolders/IsRootFolderプロパティ
Filesプロパティはフォルダ内のファイルの一覧を取得するプロパティであり、SubFoldersプロパティはサブフォルダの一覧を取得するプロパティである。この2つのプロパティを活用することで、フォルダの階層構造をたどりながら処理をすることが可能となる。
最も典型的な利用法は、特定のフォルダの中にあるすべてのファイルの処理だろう。特定のフォルダ直下にあるファイルはFilesプロパティで取得できるし、サブフォルダ内のファイルを取得するには、SubFoldersプロパティで取得できるすべてのサブフォルダのFilesプロパティを確認すればよい。
FilesプロパティやSubFoldersプロパティはコレクション・オブジェクトを返す。コレクション・オブジェクトの中身を順に処理するには、VBScriptのFor Each文を用いる。また、コレクション・オブジェクトのCountプロパティにより個数を取得することができる。ほかのコレクション同様、Itemプロパティも用意されているが、連番ではなく、ファイル名やフォルダ名をItemプロパティに渡すことで、対応するFileオブジェクトやFolderオブジェクトが得られるという仕組みになっており、ファイル名/フォルダ名にかかわらず、すべての要素を処理したい場合には、Itemプロパティは利用できない。なお、JScriptでは、Enumeratorオブジェクトを用いてすべての要素にアクセスする。
次の例では、特定のフォルダ内のファイルの一覧とサブフォルダの一覧を表示する。
1: Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")
2: Set objFolder = objFSO.GetFolder("D:\WSH\Folder1")
3:
4: WScript.Echo objFolder.Path & "内のファイル:"
5: For Each objFile In objFolder.Files
6: WScript.Echo " " & objFile.Name
7: Next
8:
9: WScript.Echo objFolder.Path & "内のサブフォルダ:"
10: For Each objSubFolder In objFolder.SubFolders
11: WScript.Echo " " & objSubFolder.Name
12: Next
実行すると次のようにファイルとサブフォルダが表示される。
D:\WSH>cscript files.vbs
D:\WSH\Folder1内のファイル:
Test1.txt
Test2.txt
Test3.txt
D:\WSH\Folder1内のサブフォルダ:
SubFolder1
SubFolder2
D:\WSH>
サブフォルダ内も含めて特定のフォルダ内のすべてのファイルを処理するには、次のようにプロシージャを作り、再帰的に処理を行うようにする。この例では「D:\WSH\Folder1」以下のすべてのファイルの読み取り専用属性を解除する。
1: Sub TurnOffReadOnly(objFolder)
2: ' フォルダ自体のreadonly属性を解除
3: objFolder.Attributes = (objFolder.Attributes And (255 - 1))
4: ' 直下のファイルのreadonly属性を解除
5: For Each objFile In objFolder.Files
6: objFile.Attributes = (objFile.Attributes And (255 - 1))
7: Next
8: ' 再帰的にサブフォルダのreadonly属性を解除
9: For Each objSubFolder In objFolder.SubFolders
10: TurnOffReadOnly(objSubFolder)
11: Next
12: End Sub
13:
14: Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")
15: Set objFolder = objFSO.GetFolder("D:\WSH\Folder1")
16: TurnOffReadOnly(objFolder)
IsRootFolderプロパティはFolderオブジェクトがルートフォルダであればTrueを、そうでなければFalseを返す。次の例では、親フォルダを順に列挙する。
1: Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")
2: Set objFolder = objFSO.GetFolder("D:\WSH\Folder1\SubFolder1")
3: Do Until objFolder.IsRootFolder
4: WScript.Echo objFolder.Name
5: Set objFolder = objFolder.ParentFolder
6: Loop
7: WScript.Echo objFolder.Path & "(ルートフォルダ)"
実行するとobjFolderがルートフォルダとなるまで繰り返され、次のように表示される。
D:\WSH>cscript parent.vbs
SubFolder1
Folder1
WSH
D:\(ルートフォルダ)
D:\WSH>
Copyright© Digital Advantage Corp. All Rights Reserved.