在.NET中,如何获取符号链接(或重新分析点)的目标?

在.NET中,我认为我可以通过调用System.IO.File.GetAttributes()并检查ReparsePoint位来确定文件是否是符号链接。 像这样:

var a = System.IO.File.GetAttributes(fileName); if ((a & FileAttributes.ReparsePoint) != 0) { // it's a symlink } 

在这种情况下,如何获得符号链接的目标?


ps:我知道如何创建符号链接。 它需要P / Invoke:

 [Interop.DllImport("kernel32.dll", EntryPoint="CreateSymbolicLinkW", CharSet=Interop.CharSet.Unicode)] public static extern int CreateSymbolicLink(string lpSymlinkFileName, string lpTargetFileName, int dwFlags); 

您必须使用DeviceIoControl()并发送FSCTL_GET_REPARSE_POINT控制代码。 P / Invoke和API使用细节非常坚韧,但Googles确实很好 。

基于提到GetFinalPathNameByHandle的答案,这里是GetFinalPathNameByHandle此操作的C#代码(因为所有其他答案只是指针):

用法

 var path = NativeMethods.GetFinalPathName(@"c:\link"); 

码:

 public static class NativeMethods { private static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1); private const uint FILE_READ_EA = 0x0008; private const uint FILE_FLAG_BACKUP_SEMANTICS = 0x2000000; [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] static extern uint GetFinalPathNameByHandle(IntPtr hFile, [MarshalAs(UnmanagedType.LPTStr)] StringBuilder lpszFilePath, uint cchFilePath, uint dwFlags); [DllImport("kernel32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] static extern bool CloseHandle(IntPtr hObject); [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern IntPtr CreateFile( [MarshalAs(UnmanagedType.LPTStr)] string filename, [MarshalAs(UnmanagedType.U4)] uint access, [MarshalAs(UnmanagedType.U4)] FileShare share, IntPtr securityAttributes, // optional SECURITY_ATTRIBUTES struct or IntPtr.Zero [MarshalAs(UnmanagedType.U4)] FileMode creationDisposition, [MarshalAs(UnmanagedType.U4)] uint flagsAndAttributes, IntPtr templateFile); public static string GetFinalPathName(string path) { var h = CreateFile(path, FILE_READ_EA, FileShare.ReadWrite | FileShare.Delete, IntPtr.Zero, FileMode.Open, FILE_FLAG_BACKUP_SEMANTICS, IntPtr.Zero); if (h == INVALID_HANDLE_VALUE) throw new Win32Exception(); try { var sb = new StringBuilder(1024); var res = GetFinalPathNameByHandle(h, sb, 1024, 0); if (res == 0) throw new Win32Exception(); return sb.ToString(); } finally { CloseHandle(h); } } } 

打开该文件 ,然后将句柄传递给GetFinalPathNameByHandle 。