←
▼
▲
Dim File::DateLastModified as Date
Set g_fs = CreateObject("Scripting.FileSystemObject")
Set file = g_fs.GetFile("list.txt")
WScript.Echo file.DateLastModified
サンプル:
キーワード:
Set g_fs = CreateObject("Scripting.FileSystemObject")
WScript.Echo g_fs.GetFile("list.txt").DateLastModified
関連
タイムスタンプに依存するテストは、ソースのバージョン管理ソフトを使うと、
正しく動かない可能性があります。 なぜなら、バージョン管理ソフトは
タイムスタンプを勝手に変えてしまうからです。
この問題に対処するには、テストで使うファイルを zip 圧縮しておきます。
←
▼
▲
Dim File::Attributes as Long
ReadOnly 定数(=1) などが使えます
属性。 読み取り専用、隠しファイルなど
サンプル
Set file = g_fs.GetFile( path )
file.Attributes = file.Attributes and not ReadOnly
file = Empty
←
▼
▲
.DateCreated
.DateLastModified
.DateLastAccessed
プロパティ
.Copy
.Delete
.Move
.OpenAsTextStream
メソッド
.Size
.Type
.Attributes
直下のファイル(
直下のサブフォルダ(Folder オブジェクト)のコレクション
.Path
.Name
.ShortPath
.ShortName
フルパス (処理が遅いです)
フォルダ名 (処理が遅いです)
フルパス(8.3形式)
フォルダ名(8.3形式)
.Drive
.ParentFolder
.IsRootFolder
.Files
.SubFolders
Drive オブジェクト
親フォルダ(Folder オブジェクト)
作成日時(取得のみ)
更新日時(取得のみ)
アクセス日時(取得のみ)
)のコレクション
Folder オブジェクトは、FileSystemObject::GetFolder で、取得できます。
取得
フォルダが削除されると、Folder オブジェクトのメンバーにはアクセスできなくなります。
Dim g_fs, fo
Set g_fs = CreateObject("Scripting.FileSystemObject")
Set fo = g_fs.GetFolder( "C:\folder" )
←
▼
▲
.Count
For Each i In Folder::Files
フォルダの中のファイルの数。サブフォルダの中は除く
File オブジェクトを参照する
をループする
Function Folder::Files.Item( FileName as string ) as File
FileName で指定したファイル名に一致するファイルオブジェクトを返します。
注意: FileName に変数を指定するときは、次のように型を指定してください。
Dim fo, fname
Set fo = g_fs.GetFolder( folder_path )
fname = "1.txt"
Set f = fo.Files.Item( CStr( fname ) )
CStr
←
▼
▲
Dim Folder::SubFolders as Folders
直下のサブフォルダ。
Set folder = g_fs.GetFolder( "." )
For Each sub_folder In folder.SubFolders '// sub_folder as Folder
echo sub_folder.Name
Next
echo folder.SubFolders.Count
サンプル
←
▼
▲
や
の返り値です。
関連
TextStream は、次の関数から取得できます。
←
▼
▲
Function TextStream::Read( n as integer ) as string
テキストストリームから指定文字数だけ取り出し、ストリームポインタを進めます。
【引数】
n
取り出す文字数(*1)
テキストストリームから取り出した内容
返り値
(*1)
非 Unicode で開いたときは、2バイトからなるマルチバイト文字(漢字など)
も 1文字として数えます。バイト数ではありません。
改行文字は、0D 0A のときは2文字として数えます。
←
▼
▲
Function TextStream::ReadLine() as string
テキストストリームから1行取り出し、ストリームポインタを1行進めます。
関連
【引数】
返り値
テキストストリームから取り出した1行
31 32 33 0D 0A 34 35 0D 0A 36
ファイル(*1)
返り値
31 32 33
31 32 33
31 32 33 0A 34 35 0D 0A 36
31 32 33 0D 34 35 0D 0A 36
Len(*2)
34 35 0D 0A 36
3
34 35 0D 0A 36
3
→ 改行コード
36
31 32 33 0D 34 35
6
EOF(*3)
False
31 32 33
True
31 32 33 0D 0A
False
False
True
31 32 33
31 32 33
3
3
(*1) ストリームポインタが指すデータ。灰色の部分は、次回以降の
ReadLine で読む値
(*2) Len( 返り値 ) の値
(*3) ReadLine 実行後の TextStream::AtEndOfStream の返り値
改行コードの違いによる動き
0D(vbCR), 0A(vbLF) と、0A は、1回の ReadLine で取れる区切りになります。
0D は、改行文字として返り値の中に入ります。Echo すると改行されます。
改行文字かどうかは、ウォッチで asc(mid( line, 1 )) と入力して表示される
文字コードから判別できます。
返り値に、改行文字は含まれません。
1行が 2MB 以上であっても取得できます。
Shell:Exec で起動したプログラムから出力される標準出力ストリームに改行
コードがないときは、本関数の中で待ち状態に入ります。
プログラムが終了したら、待ち状態から抜けます。
バイナリファイル
2種類の改行文字(0D,0A と 0A) が区別できないので、バイナリデータを
完全に取得することはできません。
TextStream::ReadAll は、完全にバイナリデータを取得できます。
←
▼
▲
Function TextStream::ReadAll() as string
テキストストリームから全て取り出します。
【引数】
返り値
テキストストリームから取り出した内容
2MB 以上であっても取得できます。
返り値は、Len でサイズを取得してもファイルサイズではありません。
0x0D 0x0A を 0x0D に変換しません。
0x00 も取得できます。
0xEAEB は、0x8145 に変わります。
←
▼
▲
Sub TextStream::Skip( n as integer )
テキストストリームを指定した文字数だけスキップします。
←
▼
▲
Sub TextStream::SkipLine()
テキストストリームを1行スキップします。
path = "a.txt"
Set g_fs = WScript.CreateObject( "Scripting.FileSystemObject" )
Set f = g_fs.OpenTextFile( path )
Do Until f.AtEndOfStream
line = f.ReadLine()
If line = "point" Then
i_line = f.Line - 1 '// 行番号を取得。(*1)
Exit Do
End If
Loop
WScript.Echo "i_line = " & i_line
Set f = g_fs.OpenTextFile( path )
For i=1 To i_line - 1 : f.SkipLine : Next '// 行へジャンプ
WScript.Echo f.ReadLine() '// "point" が書いてある行
f = Empty
g_fs = Empty
(*1) ReadLine した後なので、line の行番号は f.Line 行目ではなく f.Line-1 行目
←
▼
▲
Property Get TextStream::Line() as integer
テキストストリームの現在の行番号。(1〜)
次にアクセスする行番号。
1行目をリード/ライトしたら、Line = 2 になります。
ファイルの最後の行をリードしたときは、+1されません。
←
▼
▲
Dim TextStream::AtEndOfStream as boolean
ストリームの最後なら True
Shell:Exec で起動したプログラムから出力される標準出力ストリームに
バッファリングされた文字がないときは、False を返します。
標準入力ストリームにバッファリングされた文字がないときは、待ち状態に
入ります。改行文字がバッファリングされ、改行文字の前に文字が入力されて
いなかったら True、文字が入力されていたら False を返します。
ファイルの最後が改行文字のとき、その改行文字をリードしたら、AtEndOfStream
= True になります。
end (Return)
f.AtEndOfStream = False
ReadLine = "end"
f.AtEndOfStream = True
ファイル
メソッドの結果
リードした内容が入っている変数が無効かどうかではなく、最後の行かどうかです。
変数 = Null にしておけば、空行である "" と一致しません。
変数 = Empty にしておけば、空行である "" と一致します。
Do Until file.AtEndOfStream
line = file.ReadLine()
Loop
サンプル
補足
←
▼
▲
Sub TextStream::Write( Text as string )
テキストストリームに出力します。
←
▼
▲
Sub TextStream::WriteLine( Text as string )
テキストストリームにテキストと改行を出力します。
←
▼
▲
Sub TextStream::WriteBlankLines( LengthOfLine as integer )
テキストストリームに複数の改行を出力します。
←
▼
▲
'********************************************************************************
' <<< [EchoStream] echo supported No vbCRLF >>>
'********************************************************************************
Dim g_EchoStreamBuf
Sub EchoStream( StreamIn, StreamOut )
Dim s, c
Do Until StreamIn.AtEndOfStream
c = StreamIn.Read(1)
If g_EchoStreamBuf="続行するには何かキーを押してください . . ." Then
Stop
End If
If c <> vbCR and c <> vbLF Then _
g_EchoStreamBuf = g_EchoStreamBuf + c
If c = vbLF Then
WScript.Echo vbCR + g_EchoStreamBuf : g_EchoStreamBuf = ""
Else
StreamOut.Write c
End If
Loop
End Sub
で起動したコマンドライン・プログラムでは、バッチファイルの pause が正しく
動きません。
WshScriptExec::StdIn.ReadLine を呼ぶと、改行コードが入力されるまで戻ってきません。
WshScriptExec::StdIn.AtEndOfStream や、Read、ReadAll もなぜか戻ってきません。
このため、pause で表示される「続きを実行するとき…」のメッセージは表示されません。
1文字ずつ表示しても、文字の終了が AtEndOfStream で判定しようとすると戻ってこなく
なるので、使えません。
1文字ずつ表示する echo だが、AtEndOfStream で止まることの実証コード:
2&>1 で標準エラー出力を標準出力にリダイレクトすると、止まらないことがあります。
←
▼
▲
CopyFile、MoveFile
dst 引数
src 引数
ファイル a.txt
コピー先フォルダ C:\dst_folder が存在するとき
動作
C:\dst_folder
エラー 800A0046 書き込みできません
C:\dst_folder\a.txt
dst_folder に a.txt をコピーします
C:\dst_folder\b.txt
ファイル名を b.txt に変えてコピーします
CopyFolder、MoveFolder
エラー 800A004C パスが見つかりません
C:\dst_folder\bb\cc
フォルダ aa を dst_folder の中にコピーします
C:\dst_folder\aa
フォルダ aa の内容を dst_folder にコピーします
C:\dst_folder
動作
フォルダ aa
src 引数
dst 引数
コピー先フォルダ C:\dst_folder が存在するとき
に指定するパスがどうなっているかどうかで、
どのような動きをするかをまとめています。
C:\dst_folder\c\d.txt
エラー 800A004C パスが見つかりません
フォルダ名を bb に変えてコピーします
C:\dst_folder\bb
ワイルドカードは、コピー先にマッチしないときに限り使えます。
フォルダ名を変えることはできません。
ワイルドカード
C:\dst_folder
dst_folder にファイルをコピーします
フォルダはコピーしません
C:\dst_folder\c
エラー 800A004C パスが見つかりません
ワイルドカード
C:\dst_folder
フォルダを dst_folder の中にコピーします
なお、vbslib の
ありません。
は、指定したパスがどうなっているかどうかによって動きが変わることは
src にワイルドカードがあるときは、dst はフォルダーとして処理します。
dst がフォルダーとして存在するときは、そのフォルダーの中にコピーします。
そうでないときは、dst がファイルとして処理します。
←
▼
▲
Set fs = CreateObject("Scripting.FileSystemObject")
fs.CopyFolder "public", "dst\public", True
Set fs = Nothing
新しくできるフォルダ名
または、上書きするフォルダ名まで含める
WinCE = "C:\WINCE420"
If MsgBox( "coredllをインストールします。"+Chr(13)+WinCE+"\platform\SG2_VR5500\drivers\ipLib\ipLibCom\ipLib-com.h" _
+Chr(13)+WinCE+"\private\WINCEOS\COREOS\CORE\DLL"+Chr(13)+_
WinCE+"\public\common\cesysgen\Makefile"+Chr(13)+_
"を上書きし、"+Chr(13)+_
WinCE+"\PLATFORM\SG2_VR5500\INC\ipLibCom.h などを作成します。"+Chr(13)+_
"よろしいですか? (ドライブは合っていますか?)"+Chr(13)+_
"(リビルドするときや他の環境で使うときは、アンインストールしてください。)" ,_
vbYesNo + vbExclamation, "上書き確認" ) = vbYes Then
Set fs = CreateObject("Scripting.FileSystemObject")
fs.CopyFolder "platform", WinCE+"\platform", TRUE
fs.CopyFolder "private", WinCE+"\private", TRUE
fs.CopyFolder "public", WinCE+"\public", TRUE
Set fs = Nothing
Set sh = WScript.CreateObject("WScript.Shell")
sh.Run WinCE+"\PLATFORM\SG2_VR5500\DRIVERS\ipLib\ipLib-Headers-maker.vbs",1,True
Set sh = Nothing
MsgBox "インストールが完了しました。"
End If
Sub main()
Set args = WScript.Arguments
If args.Count <> 2 Then MsgBox "This is update files copy script" _
+vbCR+"ex) WScript.exe xcopy_pb.vbs c:\folder1 c:\folder2", vbOKOnly, "xcopy_pb" : Exit Sub
Set fs = CreateObject( "Scripting.FileSystemObject" )
Set folder1 = fs.GetFolder( args(0) )
Set folder2 = fs.GetFolder( args(1) )
For Each file In folder1.Files
fname1 = args(0) + "\" + file.Name
fname2 = args(1) + "\" + file.Name
Set file1 = fs.GetFile( fname1 )
On Error Resume Next
Set file2 = fs.GetFile( fname2 )
On Error Goto 0
If IsEmpty( file2 ) Then
fs.CopyFile fname1, fname2
ElseIf file1.DateLastModified > file2.DateLastModified Then
fs.CopyFile fname1, fname2
End If
Next
End Sub
main
(サブフォルダはコピーしません)
←
▼
▲
Dim g_fs, folder, file
Set g_fs = WScript.CreateObject( "Scripting.FileSystemObject" )
Set folder = g_fs.GetFolder( "c:\folder" )
For Each file In folder.Files
file.Name, file.Path ' ここに処理を書く
Next
fo = Empty
g_fs = Empty
Dim g_fs, folder, subfo
Set g_fs = WScript.CreateObject( "Scripting.FileSystemObject" )
Set folder = g_fs.GetFolder( "c:\folder" )
For Each sub_folder In folder.SubFolders
sub_folder.Name, sub_folder.Path ' ここに処理を書く
Next
fo = Empty
g_fs = Empty
Set g_fs = CreateObject("Scripting.FileSystemObject")
EnumSubFolders g_fs.GetFolder( "C:\folder" )
Sub EnumSubFolders( fo )
For Each f in fo.Files
f.Name, f.Path ' ここに処理を書く
Next
For Each subfo in fo.SubFolders
EnumSubFolders subfo
Next
End Sub
サンプル:
SubFolders.vbs.lzh
サブフォルダのすべてのファイルにコマンドを実行し、
標準出力をファイルに出力します。
フォルダの中にあるファイルの一覧です。
フォルダの中のフォルダについては、
フォルダの中にあるフォルダの一覧です。
フォルダの中のファイルについては、
Dim i
For i = 1 To 9999
If i<9999 Then On Error Resume Next 'try
If i=1 Then : Test_LogFName = "test_log.txt"
Else : Test_LogFName = "test_log" & i & ".txt" : End If
Set g_log = g_fs.CreateTextFile( Test_LogFName, True, False )
e.Copy( Err ) : On Error GoTo 0 : If e.num <> 0 Then 'catch
If e.num <> 70 Then e.Raise
Else
Exit For
End If
Next
→ ファイル一覧
関連