如何在c#中获取文件夹的唯一NTFS文件ID?
答案 0 :(得分:5)
internal static Int64 GetDirectoryId(string dir)
{
var handle = CreateFile(dir, FileAccess.Read, FileShare.Read, IntPtr.Zero, FileMode.Open, 0x02000000 | 0x00000080, IntPtr.Zero);
var fileStruct = new FILE_ID_BOTH_DIR_INFO();
GetFileInformationByHandleEx(handle, FILE_INFO_BY_HANDLE_CLASS.FileIdBothDirectoryInfo, out fileStruct, (uint)Marshal.SizeOf(fileStruct));
CloseHandle(handle);
var win32Error = Marshal.GetLastWin32Error();
if (win32Error != 0)
throw new Win32Exception();
return fileStruct.FileId.QuadPart;
}
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool GetFileInformationByHandleEx(
IntPtr hFile,
FILE_INFO_BY_HANDLE_CLASS infoClass,
out FILE_ID_BOTH_DIR_INFO dirInfo,
uint dwBufferSize);
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
private static extern IntPtr CloseHandle(
IntPtr handle);
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
private static extern IntPtr CreateFile(
string lpFileName,
[MarshalAs(UnmanagedType.U4)] FileAccess dwDesiredAccess,
[MarshalAs(UnmanagedType.U4)] FileShare dwShareMode,
IntPtr lpSecurityAttributes,
[MarshalAs(UnmanagedType.U4)] FileMode dwCreationDisposition,
uint dwFlagsAndAttributes,
IntPtr hTemplateFile);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
private struct FILE_ID_BOTH_DIR_INFO
{
public uint NextEntryOffset;
public uint FileIndex;
public LARGE_INTEGER CreationTime;
public LARGE_INTEGER LastAccessTime;
public LARGE_INTEGER LastWriteTime;
public LARGE_INTEGER ChangeTime;
public LARGE_INTEGER EndOfFile;
public LARGE_INTEGER AllocationSize;
public uint FileAttributes;
public uint FileNameLength;
public uint EaSize;
public char ShortNameLength;
[MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 12)]
public string ShortName;
public LARGE_INTEGER FileId;
[MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 1)]
public string FileName;
}
[StructLayout(LayoutKind.Explicit, Size=8)]
private struct LARGE_INTEGER
{
[FieldOffset(0)]public Int64 QuadPart;
[FieldOffset(0)]public UInt32 LowPart;
[FieldOffset(4)]public Int32 HighPart;
}
private enum FILE_INFO_BY_HANDLE_CLASS
{
FileIdBothDirectoryInfo = 10
}