C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[5]: 更新日付の取得でエラー


(過去ログ 112 を表示中)

[トピック内 6 記事 (1 - 6 表示)]  << 0 >>

■66539 / inTopicNo.1)  更新日付の取得でエラー
  
□投稿者/ ゆら (1回)-(2013/05/03(Fri) 11:32:32)

分類:[C#] 

お世話になります。
FindFirstFile、FindNextFileでファイルの一覧を取得しようとしているのですが、
更新日付の取得部分でエラーがでてしまいました。

[StructLayout(LayoutKind.Sequential)]
public struct FileTime
{
public uint dwLowDateTime;
public uint dwHighDateTime;
}

[StructLayout(LayoutKind.Sequential)]
public struct SYSTEMTIME {
public int wYear;
public int wMonth;
public int wDayOfWeek;
public int wDay;
public int wHour;
public int wMinute;
public int wSecond;
public int wMilliseconds; }

[StructLayout(LayoutKind.Sequential)]
public struct Win32FindData
{
public uint dwFileAttributes;
public FileTime ftCreationTime;
public FileTime ftLastAccessTime;
public FileTime ftLastWriteTime;
public uint nFileSizeHigh;
public uint nFileSizeLow;
public uint dwReserved0;
public uint dwReserved1;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string cFileName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
public string cAlternateFileName;
}


[DllImport("kernel32.dll")]
public static extern int FileTimeToSystemTime(
[MarshalAs(UnmanagedType.Struct)] ref FILETIME lpFileTime,
[MarshalAs(UnmanagedType.Struct)] ref SYSTEMTIME lpSystemTime);

[DllImport("kernel32.dll")]
public static extern int FileTimeToLocalFileTime(
[MarshalAs(UnmanagedType.Struct)] ref FILETIME lpFileTime,
[MarshalAs(UnmanagedType.Struct)] ref FILETIME lpLocalFileTime);


※fdはWin32FindData型
※ftはFileTile型
※fsはSYSTEMTIME型

FileTimeToLocalFileTime(ref fd.ftLastWriteTime, ref ft); //エラー発生部分
FileTimeToSystemTime(ref ft, ref st); //エラー発生部分

最初のエラー発生部分で以下のようなメッセージが出ております。
D:\TestTool\Form1.cs(1921,6): エラー CS1502: 'TestTool.fmMain.FileTimeToLocalFileTim(ref System.Runtime.InteropServices.FILETIME, ref System.Runtime.InteropServices.FILETIME)' に最も適しているオーバーロード メソッドには無効な引数がいくつか含まれています。
2つ目も同様に無効な引数となっています。

どのような記載をすればよろしいでしょうか。

VisualStudio2010 C#
Win7

以上、よろしくお願いします。


引用返信 編集キー/
■66541 / inTopicNo.2)  Re[1]: 更新日付の取得でエラー
□投稿者/ 魔界の仮面弁士 (206回)-(2013/05/03(Fri) 11:48:31)
No66539 (ゆら さん) に返信
> ※ftはFileTile型
これは、FimeTime型のことですね?


> FileTimeToLocalFileTime(ref fd.ftLastWriteTime, ref ft); //エラー発生部分
ref FILETIME と宣言された API に対して、
ref FimeTime な変数を渡しているからかと。
引用返信 編集キー/
■66543 / inTopicNo.3)  Re[2]: 更新日付の取得でエラー
□投稿者/ ゆら (2回)-(2013/05/03(Fri) 22:24:47)
魔界の仮面弁士様
ご回答、ありがとうございました。
単純なスペルミスだったのですね。コンパイルエラーにならなかったので気が付きませんでした(汗。

FILETIME型はもともと宣言されていて使用できるんですね。
FileTime型の宣言を消去し、FILETIME型を使ったところ、コンパイルもとおりました。

さて、更新日時を取得しようとしていますが、うまく取れずに困っています。

nn=FileTimeToLocalFileTime(ref fd.ftLastWriteTime, ref ft);
nn=FileTimeToSystemTime(ref ft, ref st);
itm.SubItems.Add(string.Format("{0}/{1}/{2} {3}:{4}:{5}",
st.wYear.ToString(), st.wMonth.ToString(), st.wDay.ToString(),
st.wHour.ToString(), st.wMinute.ToString(), st.wSecond.ToString()));

FindFirstFile、FindNextFileで取得したWin32FindData構造体をもとに更新日時を取得したいのですが、
ネットで見つけたサンプルをもとに上記のようにやってみたところ、表示される更新日時が「67545/1769474/8 0:0:0」のようにでたらめな状態となってしまいました。
この場合、どのようにすれば正しい更新日時が取得できるのでしょうか。

申し訳ございませんが、ご教示いただきたく、よろしくお願いします。

引用返信 編集キー/
■66544 / inTopicNo.4)  Re[3]: 更新日付の取得でエラー
□投稿者/ Hongliang (55回)-(2013/05/04(Sat) 01:00:31)
SYSTEMTIME構造体はメンバが全てWORD、つまり16ビット値ですよ。
引用返信 編集キー/
■66547 / inTopicNo.5)  Re[4]: 更新日付の取得でエラー
□投稿者/ ゆら (4回)-(2013/05/04(Sat) 09:53:35)
No66544 (Hongliang さん) に返信
> SYSTEMTIME構造体はメンバが全てWORD、つまり16ビット値ですよ。

Hongliangさん、お世話になります。
以下のサイトで調べた定義を使ってたので、そこは疑ってなかったです。
http://www.codegod.com/Win32APIViewer.aspx

正常にとることができました。
ご指摘、ありがとうございました。

                     以上
解決済み
引用返信 編集キー/
■66550 / inTopicNo.6)  Re[5]: 更新日付の取得でエラー
□投稿者/ 魔界の仮面弁士 (208回)-(2013/05/04(Sat) 18:17:21)
# 解決済みのようですが、一応補足として。

No66543 (ゆら さん) に返信
> Win32FindData構造体をもとに
SDK 的には、WIN32_FIND_DATA 構造体が本来の名前ですね。


> 更新日時を取得したいのですが、
DATETIME 値からの変換なら、DateTime/DateTimeOffset クラスの
FromFileTime メソッドが使えますよ。逆変換は ToFileTime メソッドで。

// unsafe コード
DateTimeOffset modified = DateTimeOffset.FromFileTime(*(long*)&fd.ftLastWriteTime);

ポインタ操作だと都合が悪いなら、予め構造体宣言時のメンバーを、
FILETIME 型ではなく long で宣言しておくのもアリです。


あるいは上位32bit/下位32bitを自前で繋ぎあわせるとか。

ft = fd.ftLastWriteTime;
long fileTime = unchecked((long)((((ulong)ft.dwHighDateTime) << 32) | (uint)ft.dwLowDateTime));
DateTimeOffset modified = DateTimeOffset.FromFileTime(fileTime);
// string ss = String.Format(@"{0:yyyy\/MM\/dd HH\:mm\:ss}", modified);



No66539 (ゆら さん) に返信
> FindFirstFile、FindNextFileで
FindClose も忘れずに。


> ファイルの一覧を取得しようとしているのですが、
今回、あえて API で操作しようとしておられるようですが、
DirectoryInfo クラスの GetFileSystemInfos メソッドでは
何か都合が悪かったのでしょうか。


> FileTimeToLocalFileTime(ref fd.ftLastWriteTime, ref ft);
> FileTimeToSystemTime(ref ft, ref st);
変換関数なので、ref, ref ではなく ref, out で宣言した方がよろしいかと。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -