我想编写一个程序,显示带有硬链接的其他驱动器的文件.我想保持两个硬链接在文件名和其他内容一致,所以我必须得到一个函数/方法,我可以列出文件的所有当前硬链接.
例如:
我有一个文件C:\ file.txt和第二个到D:\ file.txt的硬链接.
然后我将D:\ file.txt重命名为D:\ file_new.txt.我现在也希望能够重命名C驱动器上的硬链接.
所以我需要一个返回D:\ file_new.txt的函数,有以下
硬链接:
C:\ file.txt
D:\ file_new.txt
然后我可以重命名C:\上的硬链接来获取D:\ file_new .文本
所以我需要获取物理文件的所有硬链接.或者:使用硬链接寻址的文件的所有硬链接.
希望有人可以帮忙!
编辑:
Oliver注意到硬链接不能用于不同的磁盘.谢谢...所以我把问题扩展到:我需要什么?交汇点?符号链接?它还应该不仅与文件夹的文件一起使用!
以下代码应该运行良好(最初由Peter provost在PowerShell代码库上提出):
using System; using System.Collections.Generic; using System.IO; using System.Runtime.InteropServices; using System.Text; using Microsoft.Win32.SafeHandles; using FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME; namespace HardLinkEnumerator { public static class Kernel32Api { [StructLayout(LayoutKind.Sequential)] public 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; } [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] static extern SafeFileHandle CreateFile( string lpFileName, [MarshalAs(UnmanagedType.U4)] FileAccess dwDesiredAccess, [MarshalAs(UnmanagedType.U4)] FileShare dwShareMode, IntPtr lpSecurityAttributes, [MarshalAs(UnmanagedType.U4)] FileMode dwCreationDisposition, [MarshalAs(UnmanagedType.U4)] FileAttributes dwFlagsAndAttributes, IntPtr hTemplateFile); [DllImport("kernel32.dll", SetLastError = true)] static extern bool GetFileInformationByHandle(SafeFileHandle handle, out BY_HANDLE_FILE_INFORMATION lpFileInformation); [DllImport("kernel32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] static extern bool CloseHandle(SafeHandle hObject); [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); [DllImport("kernel32.dll")] static extern bool GetVolumePathName(string lpszFileName, [Out] StringBuilder lpszVolumePathName, uint cchBufferLength); [DllImport("shlwapi.dll", CharSet = CharSet.Auto)] static extern bool PathAppend([In, Out] StringBuilder pszPath, string pszMore); public static int GetFileLinkCount(string filepath) { int result = 0; SafeFileHandle handle = CreateFile(filepath, FileAccess.Read, FileShare.Read, IntPtr.Zero, FileMode.Open, FileAttributes.Archive, IntPtr.Zero); BY_HANDLE_FILE_INFORMATION fileInfo = new BY_HANDLE_FILE_INFORMATION(); if (GetFileInformationByHandle(handle, out fileInfo)) result = (int)fileInfo.NumberOfLinks; CloseHandle(handle); return result; } public static string[] GetFileSiblingHardLinks(string filepath) { Listresult = new List (); uint stringLength = 256; StringBuilder sb = new StringBuilder(256); GetVolumePathName(filepath, sb, stringLength); string volume = sb.ToString(); sb.Length = 0; stringLength = 256; IntPtr findHandle = FindFirstFileNameW(filepath, 0, ref stringLength, sb); if (findHandle.ToInt32() != -1) { do { StringBuilder pathSb = new StringBuilder(volume, 256); PathAppend(pathSb, sb.ToString()); result.Add(pathSb.ToString()); sb.Length = 0; stringLength = 256; } while (FindNextFileNameW(findHandle, ref stringLength, sb)); FindClose(findHandle); return result.ToArray(); } return null; } } }