@msdn=http://search.microsoft.com/search/results.aspx?qu=$$$ @pinvoke=http://pinvoke.net/$$$.htm Summary: Contains information about the file that is found by the FindFirstFile, FindFirstFileEx, or FindNextFile function. !!!!C# Definition: // The CharSet must match the CharSet of the corresponding PInvoke signature [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)] struct WIN32_FIND_DATA { public uint dwFileAttributes; public System.Runtime.InteropServices.ComTypes.FILETIME ftCreationTime; public System.Runtime.InteropServices.ComTypes.FILETIME ftLastAccessTime; public System.Runtime.InteropServices.ComTypes.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; public uint dwFileType; public uint dwCreatorType; public uint wFinderFlags; } !!!!VB.NET Definition: ' The CharSet must match the CharSet of the corresponding PInvoke signature <StructLayout(LayoutKind.Sequential, CharSet := CharSet.Auto)> _ Structure WIN32_FIND_DATA Public dwFileAttributes As UInteger Public ftCreationTime As System.Runtime.InteropServices.ComTypes.FILETIME Public ftLastAccessTime As System.Runtime.InteropServices.ComTypes.FILETIME Public ftLastWriteTime As System.Runtime.InteropServices.ComTypes.FILETIME Public nFileSizeHigh As UInteger Public nFileSizeLow As UInteger Public dwReserved0 As UInteger Public dwReserved1 As UInteger <MarshalAs(UnmanagedType.ByValTStr, SizeConst := 260)> Public cFileName As String <MarshalAs(UnmanagedType.ByValTStr, SizeConst := 14)> Public cAlternateFileName As String End Structure !!!!User-Defined Field Types: None. !!!!.net 1.1 Comment: FILETIME is in System.Runtime.InteropServices. The ComTypes namespace is introduced with .net 2.0 !!!!Notes: I actually discovered a problem using the System.Runtime.InteropServices.ComTypes.FILETIME structure for the ftLastAccessTime and ftLastWriteTime members. The FILETIME is defined by the .NET framework as a high and low component, both of type int. This worked fine in almost all cases. The problem I saw was when the file had no FILETIME information (0) as the file was created on a MAC inside of a ZIP file. When trying to get back to a DateTime using the DateTime.FromFileTimeUtc the DateTime created was 12/31/1979 23:52:50 (seven minutes and ten seconds before 1/1/1980) instead of 1/1/1980 00:00:00. I am in Arizona which always has a seven HOUR offset from GMT so I don't know if that played into the calculation or not (seven minutes vs. seven hours). When I created my own structure and defined the components as UInt32 the problem disappeared. Here is the structure I used instead. A uint would also work instead of the UInt32, I have seen that used also. /// <summary> /// Structure used for Windows API calls related to file information. /// </summary> [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct WIN32_FIND_FILETIME { /// <summary> /// Specifies the low 32 bits of the FILETIME. /// </summary> public UInt32 dwLowDateTime; /// <summary> /// Specifies the high 32 bits of the FILETIME. /// </summary> public UInt32 dwHighDateTime; } Documentation: FILETIME@msdn on MSDN Neal Park Documentation: WIN32_FIND_DATA@msdn on MSDN A Better Structure for VB.NET allows you to use DateTime.FromFileTime() !!!!VB.NET Definition: 'Use Pack:=4 to keep 8byte integers(Longs) from word alinging 'yet allowing 4byte integers and the strings to properly align 'requires: Imports System.Runtime.InteropServices <StructLayout(LayoutKind.Sequential, Pack:=4)> _ Private Structure WIN32_FIND_DATA Public dwFileAttributes As Integer Public ftCreationTime As Long Public ftLastAccessTime As Long Public ftLastWriteTime As Long Public nFileSizeHigh As UInteger Public nFileSizeLow As UInteger Public dwReserved0 As Integer Public dwReserved1 As Integer <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=260)> Public cFileName As String <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=14)> Public cAlternate As String End Structure !!!!Notes: No need for a FILETIME Structure just use DateTime.FromFileTime Dim LastWrite As DateTime = DateTime.FromFileTime(ftLastWriteTime) Better file size calculation with size elements defined as Unsigned Integers Dim FileSize As Long = ((nFileSizeHigh << 32&) Or nFileSizeLow) Ron Weller Added: I had the same problem: DateTime.FromFileTimeUtc. Solved it using: <StructLayout(LayoutKind.Sequential)> _ Public Structure FILETIME Public dwLowDateTime As UInteger Public dwHighDateTime As UInteger Public Function ToDate() As Date Dim v = CLng(dwHighDateTime) << 32 Return Date.FromFileTime(v + CLng(dwLowDateTime)) End Function End Structure OBS: FromFileTime, not FileTimeUtc. Jens Madsen (BTW, it IS the GMT that makes the difference: With 'utc' on Win7, I had the date 7/13/2009 for \system32\cmd.exe The real date is 7/14/2009 ;) (I'm from Denmark...)) (Ehh - The 'FILETIME' issues seems exhausted, but I add this one, because the use of '<StructLayout(LayoutKind.Explicit)>' has more uses that eases conversions... <StructLayout(LayoutKind.Explicit, Pack:=4, Size:=8)> _ Public Structure FILETIME <FieldOffset(0)> Public dwLowDateTime As UInteger <FieldOffset(0)> Private LongValue As Long <FieldOffset(4)> Public dwHighDateTime As UInteger Public ReadOnly Property dotNETDate As Date Get Return Date.FromFileTime(LongValue) End Get End Property Public ReadOnly Property Value() As Long Get Return LongValue End Get End Property End Structure
Edit Structures.WIN32_...
You do not have permission to change this page. If you feel this is in error, please send feedback with the contact link on the main page.