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"