VBScriptでInterface風
日頃、雑用?を担当しているせいか、くだらないことを聞きにやって来る人が何人かいる。よくあるのが、あるフォルダ下(サブフォルダも含めて)の全てのファイルに対して何かしたい、というもの。そのぐらい自分でなんとかしてよ…。
自分のマシンであればcygwin上でコマンド組み合わせたりperlで数行書いたり好き勝手にするんだけど、大抵そういう人のマシンには使えるものが入っていなく、標準のVBScriptで頑張るしかない。
いつもは使い捨てていたが、この機会?に使いまわせるように書き直しておく。
'
' tracer.vbs
'
Option Explicit
'
Class Tracer
'
Private objFso
'
Private Sub Class_Initialize()
Set objFso = CreateObject("Scripting.FileSystemObject")
End Sub
'
Private Sub Class_Terminate()
Set objFso = Nothing
End Sub
'
Public Function Run(handler, path)
Dim objFile, objFolder
' file
If objFso.FileExists(path) Then
Run = handler.HandleFile(path)
' folder
ElseIf objFso.FolderExists(path) Then
For Each objFile In objFso.GetFolder(path).Files
If Not handler.HandleFile(objFile.Path) Then
Run = False
Exit Function
End If
Next
For Each objFolder In objFso.GetFolder(path).SubFolders
If Not Run(handler, objFolder.Path) Then
Run = False
Exit Function
End If
Next
If Not handler.HandleFolder(path) Then
Run = False
Exit Function
End If
Run = True
' ?
Else
Run = False
End If
End Function
End Class
'
Sub Main(handler)
Dim objTracer, objArgs, objArg
Set objTracer = New Tracer
Set objArgs = WScript.Arguments
If objArgs.Count > 0 Then
For Each objArg In objArgs
objTracer.Run handler, objArg
Next
Else
objTracer.Run handler, "."
End If
End Sub
以下のEchoHandlerはパスを表示するだけの単純な例で、XxxHandlerクラスはその都度適当なクラス名で実装する。HandleFile()にはファイルに対する処理、HandleFolder()にはフォルダに対する処理を実装すればよい。
'
Class EchoHandler
Function HandleFile(path)
WScript.Echo path
HandleFile = True
End Function
Function HandleFolder(path)
WScript.Echo path
HandleFolder = True
End Function
End Class
'
Main New EchoHandler
c:\> cscript tracer.vbs c:\temp\
VBScriptのクラスは継承やJavaでいうInterfaceなどもない。全然使えないという意見もあるが、動的型付けなためInterfaceの定義を記述する必要がないだけで、Interface風な使い方は可能である。
特定フォルダを削除したいときはこう。
'
Class CvsDelHandler
Private objFso
Private Sub Class_Initialize()
Set objFso = CreateObject("Scripting.FileSystemObject")
End Sub
Private Sub Class_Terminate()
Set objFso = Nothing
End Sub
Function HandleFile(path)
HandleFile = True
End Function
Function HandleFolder(path)
If Right(path, 4) = "\CVS" Then
objFso.DeleteFolder path
End If
HandleFolder = True
End Function
End Class
'
Main New CvsDelHandler
多少のエラーも気にしない自分は以下のコマンドで :-)
c:\> for /r %i in (CVS) do rmdir "%i"