〜 ファイル 〜
ファイルのタイムスタンプを設定 (要KERNEL32.DLL)

ファイルの作成日時や更新日時等のタイムスタンプは、API関数SetFileTimeで設定できます。
API関数SetFileTimeで指定するのは第1引数から順に、「ファイルハンドル」
「作成日時を格納したFILETIME構造体のポインタ」
「最終アクセス日時を格納したFILETIME構造体のポインタ」
「最終書込日時を格納したFILETIME構造体のポインタ」となります。

まず、設定するファイルのハンドルを取得する必要があるので、API関数CreateFileを使います。
API関数CreateFileの第1引数はファイルパス文字列を格納した変数ポインタです。
第2引数は以下のアクセスタイプのいずれかを指定します。
0x00000000存在確認等の問い合わせのみ
GENERIC_WRITE0x40000000書込アクセス
GENERIC_READ0x80000000読込アクセス
第3引数は開いた後に他からのアクセスを許可するか否か共有設定を指定します。
0x0000共有しない。
FILE_SHARE_READ0x0001読取アクセスを許可
FILE_SHARE_WRITE0x0002書込アクセスを許可
FILE_SHARE_DELETE0x0004削除アクセスを許可
第4引数はセキュリティ属性を格納したSECURITY_ATTRIBUTES構造体のアドレスを指定しますが、 既に存在するファイルに対しては無視されるので0を入れておきましょう。 第5引数はファイルをどうするか動作を以下の定数から指定します。
CREATE_NEW0x0001新規作成(同一ファイルが存在しない場合)
CREATE_ALWAYS0x0002新規作成(同一ファイルが存在すると上書)
OPEN_EXISTING0x0003開く(ファイルが存在する場合)
OPEN_ALWAYS0x0004開く(ファイルが存在しない場合は作成)
TRUNCATE_EXISTING0x0005サイズ0にして開く(ファイルが存在する場合)
第6引数は以下のファイル属性を指定します。
FILE_ATTRIBUTE_READONLY0x0001書き込みや削除が行えない読取専用ファイル。
FILE_ATTRIBUTE_HIDDEN0x0002通常のディレクトリリスティングでは表示されない隠しファイル。
FILE_ATTRIBUTE_SYSTEM0x0004OSのシステムファイル。
FILE_ATTRIBUTE_ARCHIVE0x0020バックアップや削除のためのマークとして使用するアーカイブファイル。
FILE_ATTRIBUTE_DEVICE0x0040予約済。
FILE_ATTRIBUTE_NORMAL0x0080属性を持たないファイル。他の属性を指定しない場合に適用される。
FILE_ATTRIBUTE_TEMPORARY0x0100必要がなくなった段階ですぐに削除すべき一時ファイル。
FILE_ATTRIBUTE_SPARSE_FILE0x0200未使用領域が多いか同じ値が長く続くスパースファイル。
FILE_ATTRIBUTE_REPARSE_POINT0x0400再解析ポイントが関連付けられているファイル。
FILE_ATTRIBUTE_COMPRESSED0x0800圧縮ファイル。
FILE_ATTRIBUTE_OFFLINE0x1000データがオフラインの記憶装置へ物理的に移動されたことを示すファイル。
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED0x2000「インデックスサービス」の対象ではないファイル。(Windows2000〜)
FILE_ATTRIBUTE_ENCRYPTED0x4000暗号化ファイル。
また、以下のオプションフラグを組み合わせることも可能です。
FILE_FLAG_OPEN_NO_RECALL0x00100000ローカルストレージに移されないようにする。
FILE_FLAG_OPEN_REPARSE_POINT0x00200000NTFSのリパースポイント機能の動作を禁止。
FILE_FLAG_POSIX_SEMANTICS0x01000000MS−DOS、16ビットアプリケーションからはアクセス不可。
FILE_FLAG_BACKUP_SEMANTICS0x02000000復元作業の為、呼出プロセスがセキュリティチェックをオーバーライド。
FILE_FLAG_DELETE_ON_CLOSE0x04000000全てのファイルハンドルがクローズするとファイルを削除。
FILE_FLAG_SEQUENTIAL_SCAN0x08000000シーケンシャルアクセス用に最適化されたファイルキャッシングを行う。
FILE_FLAG_RANDOM_ACCESS0x10000000ランダムアクセス用に最適化されたファイルキャッシングを行う。
FILE_FLAG_NO_BUFFERING0x20000000システムキャッシュを使用せずにファイルをオープン。
FILE_FLAG_OVERLAPPED0x40000000ファイルポインタを保持せずファイルに複数の操作を同時に行うことが可能。
FILE_FLAG_WRITE_THROUGH0x80000000キャッシュに書き込まれたデータをそのままディスクに書き込む。
第7引数はファイル属性と拡張属性を提供するテンプレートファイルへのハンドルを指定するとありますが、 ウィンドウズ9X系は指定できず、また、既存ファイルを開く場合は無視されるので0を指定します。 以上を指定してハンドルを受け取り、使用した後はAPI関数CloseHandleで解放します。 特に下記サンプルのように共有せず開いた場合、解放するまで他からファイルアクセスが出来なくなるので、 必ずクローズするようにしてください。 ハンドルが取得できれば、続いてAPI関数SetFileTimeの第2〜4引数のFILETIME構造体をセットします。 FILETIME構造体はコチラで説明したように、1601年から100ナノ秒刻みのカウントとなるので、 設定しようとする年月日・時分秒が幾つになるかを計算して設定するのは面倒です。 そこで、まずは年月日・時分秒それぞれをセットできるSYSTEMTIME構造体に設定したい日時セットして、 SystemTimeToFileTimeFILETIME構造体に変換すると良いのですが、 実はコレだけでは不十分で、このやり方でセットしたFILETIME構造体は協定世界時としての日時であるので、 パソコンで設定されている日時(恐らく日本標準時(JST))でセットしたい場合は、 FILETIME構造体に変換した後、API関数LocalFileTimeToFileTimeも使って、 格納されたFILETIME構造体の日時を協定世界時(UTC)に変換する必要があります。 変換が終われば、それぞれのFILETIME構造体のポインタを取得して引数に設定しましょう。 ただし、最終アクセス日時は変更できないようです。 設定が正常にできたかタイムスタンプを確認するには、取得を行うコチラを参照してください。

tm2st 格納先, 年, 月, 日, 時, 分, 秒, ミリ秒
格納先日付情報を格納しておく数値型配列変数を指定する。
正常に指定していると、SYSTEMTIME型として使用可能。
格納する年を指定する。省略すれば現時点の年となる。
格納する月を指定する。省略すれば現時点の月となる。
格納する日を指定する。省略すれば現時点の日となる。
格納する時を指定する。省略すれば現時点の時となる。
格納する分を指定する。省略すれば現時点の分となる。
格納する秒を指定する。省略すれば現時点の秒となる。
ミリ秒格納するミリ秒を指定する。省略すれば現時点のミリ秒となる。

settimestamp ファイルパス, タイプ, 年, 月, 日, 時, 分, 秒
ファイルパスタイムスタンプ変更対象のファイルパスを指定する。
尚、内部でtm2st命令を使用しているため、settimestamp命令よりも前にtm2st命令を定義すること。
タイプ設定する日時項目(0:作成 1:最終書込 2:最終アクセス)を指定する。
変更後の年を指定する。省略すれば現時点の年となる。
変更後の月を指定する。省略すれば現時点の月となる。
変更後の日を指定する。省略すれば現時点の日となる。
変更後の時を指定する。省略すれば現時点の時となる。
変更後の分を指定する。省略すれば現時点の分となる。
変更後の秒を指定する。省略すれば現時点の秒となる。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
	ll_libload kernel, "kernel32.dll"
	ll_getproc CreateFileA "CreateFileA", kernel
	ll_getproc CloseHandle "CloseHandle", kernel
	ll_getproc SetFileTime "SetFileTime", kernel
	ll_getproc SystemTimeToFileTime "SystemTimeToFileTime", kernel
	ll_getproc LocalFileTimeToFileTime "LocalFileTimeToFileTime", kernel

#module
#deffunc tm2st val, int, int, int, int, int, int, int
	mref tm, 48 : mref y, 1 : mref m, 2 : mref d, 3 : mref h, 4 : mref mi, 5 : mref s, 6 : mref ms, 7
	if y = 0 : gettime y, 0
	if m = 0 : gettime m, 1
	if d = 0 : gettime d, 3
	if h = 0 & (mi = 0) & (s = 0) & (ms = 0) : gettime h, 4 : gettime mi, 5 : gettime s, 6 : gettime ms, 7
	wpoke tm.0, 0, y
	wpoke tm.0, 2, m
	wpoke tm.1, 2, d
	wpoke tm.2, 0, h
	wpoke tm.2, 2, mi
	wpoke tm.3, 0, s
	wpoke tm.3, 2, ms
	return

#deffunc settimestamp str, int, int, int, int, int, int, int
	mref file, 32 : mref type, 1 : mref y, 2 : mref m, 3 : mref d, 4 : mref h, 5 : mref mi, 6 : mref s, 7
	dim st, 4
	tm2st st, y, m, d, h, mi, s
	ll_getptr st : ll_ret prm.0
	ll_getptr ft : ll_ret prm.1
	ll_callfunc prm, 2, SystemTimeToFileTime@
	prm = prm.1
	ll_callfunc prm, 2, LocalFileTimeToFileTime@
	ll_getptr file : ll_ret prm.0
	prm.1 = 0x40000000, 0, 0, 0x0003, 0, 0
	ll_callfunc prm, 7, CreateFileA@
	ll_ret hfile
	ll_getptr ft : ll_ret prm.4
	prm = hfile, (type = 0) * prm.4, (type = 2) * prm.4, (type = 1) * prm.4
	ll_callfunc prm, 4, SetFileTime@
	ll_callfunc hfile, 1, CloseHandle@
	return
#global

	gettime d.0, 0
	gettime d.1, 1
	gettime d.2, 3
	gettime d.3, 4
	gettime d.4, 5
	gettime d.5, 6
	pos  10, 10 : input d.0, 40, 20
	pos  70, 10 : mes "年"
	pos 100, 10 : input d.1, 25, 20
	pos 140, 10 : mes "月"
	pos 170, 10 : input d.2, 25, 20
	pos 210, 10 : mes "日"
	pos  30, 40 : input d.3, 25, 20
	pos  70, 40 : mes "時"
	pos 100, 40 : input d.4, 25, 20
	pos 140, 40 : mes "分"
	pos 170, 40 : input d.5, 25, 20
	pos 210, 40 : mes "秒"
	pos  10, 70 : combox index, , "作成\n更新\nアクセス"
	pos 100, 70 : button "セット", *set
	stop

*set
	dialog "", 16, "タイムスタンプ設定対象ファイル"
	if stat : settimestamp refstr, index, d.0, d.1, d.2, d.3, d.4, d.5
	stop

tm2st 格納先, 年, 月, 日, 時, 分, 秒, ミリ秒
格納先日付情報を格納しておく数値型配列変数を指定する。
正常に指定していると、SYSTEMTIME型として使用可能。
格納する年を指定する。省略すれば現時点の年となる。
格納する月を指定する。省略すれば現時点の月となる。
格納する日を指定する。省略すれば現時点の日となる。
格納する時を指定する。省略すれば現時点の時となる。
格納する分を指定する。省略すれば現時点の分となる。
格納する秒を指定する。省略すれば現時点の秒となる。
ミリ秒格納するミリ秒を指定する。省略すれば現時点のミリ秒となる。

settimestamp ファイルパス, タイプ, 年, 月, 日, 時, 分, 秒
ファイルパスタイムスタンプ変更対象のファイルパスを指定する。
尚、内部でtm2st命令を使用しているため、settimestamp命令よりも前にtm2st命令を定義すること。
タイプ設定する日時項目(0:作成 1:最終書込 2:最終アクセス)を指定する。
変更後の年を指定する。省略すれば現時点の年となる。
変更後の月を指定する。省略すれば現時点の月となる。
変更後の日を指定する。省略すれば現時点の日となる。
変更後の時を指定する。省略すれば現時点の時となる。
変更後の分を指定する。省略すれば現時点の分となる。
変更後の秒を指定する。省略すれば現時点の秒となる。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#uselib "kernel32.dll"
#cfunc	global CreateFileA "CreateFileA" sptr, int, int, int, int, int, int
#func	global CloseHandle "CloseHandle" int
#func	global SetFileTime "SetFileTime" int, int, int, int
#func	global SystemTimeToFileTime "SystemTimeToFileTime" var, var
#func	global LocalFileTimeToFileTime "LocalFileTimeToFileTime" var, var

#module
#deffunc tm2st array tm, int y, int m, int d, int h, int mi, int s, int ms
	wpoke tm.0, 0, (y = 0) * gettime(0) + y
	wpoke tm.0, 2, (m = 0) * gettime(1) + m
	wpoke tm.1, 2, (d = 0) * gettime(3) + d
	wpoke tm.2, 0, (h = 0 & mi = 0 & s = 0 & ms = 0) * gettime(4) + h
	wpoke tm.2, 2, (h = 0 & mi = 0 & s = 0 & ms = 0) * gettime(5) + mi
	wpoke tm.3, 0, (h = 0 & mi = 0 & s = 0 & ms = 0) * gettime(6) + s
	wpoke tm.3, 2, (h = 0 & mi = 0 & s = 0 & ms = 0) * gettime(7) + ms
	return

#deffunc settimestamp str file, int type, int y, int m, int d, int h, int mi, int s, local st, local ft
	dim st, 4
	dim ft, 2
	tm2st st, y, m, d, h, mi, s
	SystemTimeToFileTime st, ft
	LocalFileTimeToFileTime ft, ft
	hfile = CreateFileA(file, 0x40000000, , , 0x0003)
	SetFileTime hfile, (type = 0) * varptr(ft), (type = 2) * varptr(ft), (type = 1) * varptr(ft)
	CloseHandle hfile
	return
#global

	d = gettime(0), gettime(1), gettime(3), gettime(4), gettime(5), gettime(6)
	pos  10, 10 : input d.0, 40, 20
	pos  70, 10 : mes "年"
	pos 100, 10 : input d.1, 20, 20
	pos 140, 10 : mes "月"
	pos 170, 10 : input d.2, 20, 20
	pos 210, 10 : mes "日"
	pos  30, 40 : input d.3, 20, 20
	pos  70, 40 : mes "時"
	pos 100, 40 : input d.4, 20, 20
	pos 140, 40 : mes "分"
	pos 170, 40 : input d.5, 20, 20
	pos 210, 40 : mes "秒"
	pos  10, 70 : combox index, , "作成\n更新\nアクセス"
	pos 100, 70 : button gosub "セット", *set
	stop

*set
	dialog "", 16, "タイムスタンプ設定対象ファイル"
	if stat : settimestamp refstr, index, d.0, d.1, d.2, d.3, d.4, d.5
	return