2016-11-13 4 views

答えて

2

GetFileInformationByHandle機能を使用して、ノードを指すハードリンクの数を取得できます。たとえば:

[DllImport("kernel32.dll", SetLastError = true)] 
static extern bool GetFileInformationByHandle(
    SafeFileHandle hFile, 
    out BY_HANDLE_FILE_INFORMATION lpFileInformation 
); 

[StructLayout(LayoutKind.Sequential)] 
struct BY_HANDLE_FILE_INFORMATION { 
    public uint FileAttributes; 
    public FILETIME CreationTime; 
    public FILETIME LastAccessTime; 
    public FILETIME LastWriteTime; 
    public uint VolumeSerialNumber; 
    public uint FileSizeHigh; 
    public uint FileSizeLow; 
    public uint NumberOfLinks; 
    public uint FileIndexHigh; 
    public uint FileIndexLow; 
} 

// then in another place 
using (var fs = File.OpenRead("path to your file")) {     
    BY_HANDLE_FILE_INFORMATION info; 
    GetFileInformationByHandle(fs.SafeFileHandle, out info); 
    var numberOfLinks = info.NumberOfLinks; 
} 

彼らが指しているどのファイルを取得するには、別の勝利API関数が必要になります。FindFirstFileNameWFineNextFileNameW

[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 
static extern IntPtr FindFirstFileNameW(
     string lpFileName, 
     uint dwFlags, 
     ref uint stringLength, 
     StringBuilder fileName); 

[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 
static extern bool FindNextFileNameW(
     IntPtr hFindStream, 
     ref uint stringLength, 
     StringBuilder fileName); 

[DllImport("kernel32.dll", SetLastError = true)] 
static extern bool FindClose(IntPtr fFindHandle); 

public static string[] GetFileHardLinks(string filePath) { 
    // first get drive letter 
    var drive = new DriveInfo(Path.GetPathRoot(filePath)); 
    var result = new List<string>(); 
    // buffer for return value 
    var sb = new StringBuilder(256); 
    // length of buffer 
    uint sbLength = 256; 
    // third argument contains reference to buffer length (buffer is StringBuilder). 
    // it's a reference because if it's too small, call returns an error and will put required length there instead 
    IntPtr findHandle = FindFirstFileNameW(filePath, 0, ref sbLength, sb); 
    // returns -1 on error 
    if (findHandle.ToInt64() != -1) { 
     do { 
      // combine the result with drive letter (it comes without it) 
      result.Add(Path.Combine(drive.RootDirectory.FullName, sb.ToString().TrimStart(new [] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar}))); 
      sb.Clear(); 
      sbLength = 256; 
      // and repeat 
     } while (FindNextFileNameW(findHandle, ref sbLength, sb)); 
     FindClose(findHandle); 
     return result.ToArray(); 
    } 
    return null; 
} 

このコードは、製造準備ができていない可能性がありますので、ご注意ください。しかし、それは少なくともあなたにアイデアを与える必要があります。もしあなたがそれを使用するならば、それらの関数がエラーで何を返すかを注意深く読んで、それに応じて行動してください(例えば、バッファの長さが足りない場合や、256より大きいバッファを使うなど)。

関連する問題