- ベストアンサー
ファイル時刻の変更直後の時刻取得
SetFileTime でファイル時刻を変更した直後にタスクを終了することなく GetFileTime でファイル時刻を取得するとなぜか変更内容が破棄されます。 タスクを終了すると変更内容が有効になっていますのでおそらくディスクキャッシュの影響とおもわれます。 関係情報・関係情報が記載されているコンパイルされたHTMLファイル・検索用シソーラス等お知らせ願えませんか。 プログラム作成環境 Visual Stiudio 6.0 Visual Basic SP5パッチ済 Windows 98SE 4.1 実行予定環境(作成時の障害の為現時点では実行経験なし) Windows 95 Windows 98
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
動作確認済みソースです。(EXCEL.VBAにて) WinXPsp2 Excel2000sp3(VBA) この環境では、Doeventsを利用しないでも、1日づつ日付が変更になりました。 OSによって違うのか、ソースに不具合があるか、実行して差を教えてください。 Option Explicit Private Const DEF_FILE As String = "C:\テスト.txt" ' セキュリティを定義する構造体 Private Type SECURITY_ATTRIBUTES nLength As Long lpSecurityDescriptor As Long bInheritHandle As Long End Type ' ファイルハンドルの値が無効であることを示す定数の宣言 Private Const INVALID_HANDLE_VALUE = (-1) ' オブジェクトへのアクセスの種類を指定する定数の宣言 Private Const GENERIC_READ = &H80000000 Private Const GENERIC_WRITE = &H40000000 ' ファイルへの動作を指定する定数の宣言 Private Const OPEN_EXISTING = 3 ' ファイルなどの作成やオープンや切り捨てを行う関数の宣言 Private Declare Function CreateFile Lib "kernel32.dll" _ Alias "CreateFileA" _ (ByVal lpFileName As String, _ ByVal dwDesiredAccess As Long, _ ByVal dwShareMode As Long, _ lpSecurityAttributes As SECURITY_ATTRIBUTES, _ ByVal dwCreationDistribution As Long, _ ByVal dwFlagsAndAttributes As Long, _ ByVal hTemplateFile As Long) As Long ' オープンされているオブジェクトハンドルをクローズする ' 関数の宣言 Private Declare Function CloseHandle Lib "kernel32.dll" _ (ByVal hObject As Long) As Long ' 日付と時刻を定義する構造体 Private Type SYSTEMTIME wYear As Integer wMonth As Integer wDayOfWeek As Integer wDay As Integer wHour As Integer wMinute As Integer wSecond As Integer wMilliseconds As Integer End Type ' ファイル時間を定義する構造体 Private Type FILETIME dwLowDateTime As Long dwHighDateTime As Long End Type ' システム時間をファイル時間に変換する関数の宣言 Private Declare Function SystemTimeToFileTime Lib "kernel32.dll" _ (lpSystemTime As SYSTEMTIME, _ lpFileTime As FILETIME) As Long ' ファイル時間をシステム時間に変換する関数の宣言 Private Declare Function FileTimeToSystemTime Lib "kernel32.dll" _ (lpFileTime As FILETIME, _ lpSystemTime As SYSTEMTIME) As Long ' ファイルの作成日時などを設定する関数の宣言 Private Declare Function SetFileTime Lib "kernel32.dll" _ (ByVal hFile As Long, _ lpCreationTime As FILETIME, _ lpLastAccessTime As FILETIME, _ lpLastWriteTime As FILETIME) As Long ' ファイルの作成日時などを取得する関数の宣言 Private Declare Function GetFileTime Lib "kernel32.dll" _ (ByVal hFile As Long, _ lpCreationTime As FILETIME, _ lpLastAccessTime As FILETIME, _ lpLastWriteTime As FILETIME) As Long Sub Test() Dim datTime As Date Debug.Print String(26, "-") '1回目取得 Call funcGetTime(DEF_FILE, datTime) Debug.Print "1.取得" & datTime '1日引いて更新 Call funcSetTime(DEF_FILE, datTime - 1) '2回目取得 Call funcGetTime(DEF_FILE, datTime) Debug.Print "2.取得" & datTime Debug.Print String(26, "-") End Sub Private Function funcGetTime(ByVal inFile As String, ByRef otTime As Date) As Boolean Dim lngOpenFileHandle As Long Dim udtCreationTime As FILETIME Dim udtLastAccessTime As FILETIME Dim udtLastWriteTime As FILETIME 'ファイルを取得モードでオープン If Not APICreateFile(inFile, False, lngOpenFileHandle) Then Exit Function End If ' ファイルの作成日時を取得 Call GetFileTime(lngOpenFileHandle, _ udtCreationTime, _ udtLastAccessTime, _ udtLastWriteTime) '【変換】ファイル時間→日付 Call FileTime_To_Date(udtLastWriteTime, otTime) 'ファイルをクローズ Call APICloseHandle(lngOpenFileHandle) funcGetTime = True End Function Private Function funcSetTime(ByVal inFile As String, ByVal inTime As Date) As Boolean Dim lngOpenFileHandle As Long Dim udtCreationTime As FILETIME Dim udtLastAccessTime As FILETIME Dim udtLastWriteTime As FILETIME 'ファイルを更新モードでオープン If Not APICreateFile(inFile, True, lngOpenFileHandle) Then Exit Function End If ' ファイルハンドルの値が無効であるときは抜ける If lngOpenFileHandle = INVALID_HANDLE_VALUE Then Exit Function End If '【変換】日付→ファイル時間 Call Date_To_FileTime(inTime, udtLastWriteTime) 'ファイルの更新日時を設定 Call SetFileTime( _ lngOpenFileHandle _ , udtCreationTime _ , udtLastAccessTime _ , udtLastWriteTime _ ) 'ファイルをクローズ Call APICloseHandle(lngOpenFileHandle) funcSetTime = True End Function Private Sub APICloseHandle(ByRef inFileHandle As Long) If inFileHandle <> 0 Then Call CloseHandle(inFileHandle) End If inFileHandle = 0 End Sub Private Function APICreateFile(ByVal inFile As String, ByVal inSetMode As Boolean, Optional ByRef otFileHandle As Long) As Boolean Dim udtSecurityAttributes As SECURITY_ATTRIBUTES Dim lngOpenFileHandle As Long '初期化 Call APICloseHandle(otFileHandle) ' セキュリティ構造体を初期化 udtSecurityAttributes.nLength = Len(udtSecurityAttributes) ' ファイルをオープン lngOpenFileHandle = _ CreateFile(inFile, _ IIf(inSetMode, GENERIC_WRITE, GENERIC_READ), _ 0, _ udtSecurityAttributes, _ OPEN_EXISTING, _ 0, _ 0) 'ステータスチェック APICreateFile = Not (lngOpenFileHandle = INVALID_HANDLE_VALUE) If APICreateFile Then '正常ケースは、ハンドルを返す otFileHandle = lngOpenFileHandle End If End Function Private Sub Date_To_FileTime(ByVal inDate As Date, otFileTime As FILETIME) Dim udtSystemTime As SYSTEMTIME '【変換】日付→システム時間 With udtSystemTime .wYear = Year(inDate) .wMonth = Month(inDate) .wDay = Day(inDate) .wHour = Hour(inDate) .wMinute = Minute(inDate) .wSecond = Second(inDate) .wMilliseconds = 0 .wDayOfWeek = Weekday(inDate) - 1 End With '【変換】システム時間→ファイル時間 Call SystemTimeToFileTime(udtSystemTime, otFileTime) End Sub Private Sub FileTime_To_Date(inFileTime As FILETIME, otDate As Date) Dim udtSystemTime As SYSTEMTIME '【変換】ファイル時間→システム時間 Call FileTimeToSystemTime(inFileTime, udtSystemTime) '【変換】システム時間→日付 With udtSystemTime otDate = .wYear & "/" & .wMonth & "/" & .wDay & " " & .wHour & ":" & .wMinute & ":" & .wSecond End With End Sub
その他の回答 (2)
- 1050 円(@1050YEN)
- ベストアンサー率69% (477/687)
CreateFile→SetFileTime→CloseHandle doevents ← これをいれても駄目ですか? CreateFile→GetFileTime→CloseHandle
お礼
だめでした。既に書いたとおりおそらくいつくかの変数名を私の好みに書き換えていることが原因です。 全削除2回・変数名を私の好みにかえないということで動作しました。おかげでブラックボックスのルーチンになってしまいました。 ただ他の少なくはない数のファイルの関係しているルーチンで正体不明のムシがファイルClose等ファイル取り扱い終了時に実行することで解決しました。
- taka_tetsu
- ベストアンサー率65% (1020/1553)
>SetFileTime でファイル時刻を変更した直後にタスクを終了することなく GetFileTime でファイル時刻を取得するとなぜか変更内容が破棄されます。 処理の流れは? もちろんSetFileTime→CloseHandle→CreateFile→GetFileTimeですよね? SetFileTime→CreateFile→GetFileTimeなんてしてないですよね? 明示的にバッファ内容を書き込ませるにはFlushFileBuffersです。 バッファの使用有無などはCreateFileのパラメータにもよります。
補足
>処理の流れは? CreateFile→SetFileTime→CloseHandle と CreateFile→GetFileTime→CloseHandle の2つのサブルーチンを呼び出しています。 >パラメータにもよります 関係定数を調べてみます。以前このサイトで教えていただいたガリバーのコピーなので大きな間違いはしていないと思います。しかし見本をサブルーチン化したときに変なことになっているかもしれません。
お礼
開発環境で実行を確認できました。 したがって、不動の原因としては、予約語の間違いが考えられます。 自分では見つけられませんので、全部削除して、もう一度作り直してみます。