从符号链接C#获取真实路径

时间:2016-07-11 05:46:43

标签: c#

有谁知道如何从符号链接文件或文件夹中获取真实路径?谢谢!

1 个答案:

答案 0 :(得分:3)

在我的研究之后,我们找到了解决方案,了解如何获得符号链接的真实路径。如果您有一个已创建的符号链接,并想要检查此文件或文件夹的实际指针在哪里。如果有人有更好的方式来写它请分享。

    [DllImport("kernel32.dll", EntryPoint = "CreateFileW", CharSet = CharSet.Unicode, SetLastError = true)]
    private static extern SafeFileHandle CreateFile(string lpFileName, int dwDesiredAccess, int dwShareMode, IntPtr SecurityAttributes, int dwCreationDisposition, int dwFlagsAndAttributes, IntPtr hTemplateFile);

    [DllImport("kernel32.dll", EntryPoint = "GetFinalPathNameByHandleW", CharSet = CharSet.Unicode, SetLastError = true)]
    private static extern int GetFinalPathNameByHandle([In] IntPtr hFile, [Out] StringBuilder lpszFilePath, [In] int cchFilePath, [In] int dwFlags);

    private const int CREATION_DISPOSITION_OPEN_EXISTING = 3;
    private const int FILE_FLAG_BACKUP_SEMANTICS = 0x02000000;


    public static string GetRealPath(string path)
    {
        if (!Directory.Exists(path) && !File.Exists(path))
        {
            throw new IOException("Path not found");
        }

        DirectoryInfo symlink = new DirectoryInfo(path);// No matter if it's a file or folder
        SafeFileHandle directoryHandle = CreateFile(symlink.FullName, 0, 2, System.IntPtr.Zero, CREATION_DISPOSITION_OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, System.IntPtr.Zero); //Handle file / folder

        if (directoryHandle.IsInvalid)
        {
            throw new Win32Exception(Marshal.GetLastWin32Error());
        }

        StringBuilder result = new StringBuilder(512);
        int mResult = GetFinalPathNameByHandle(directoryHandle.DangerousGetHandle(), result, result.Capacity, 0);

        if (mResult < 0)
        {
            throw new Win32Exception(Marshal.GetLastWin32Error());
        }

        if (result.Length >= 4 && result[0] == '\\' && result[1] == '\\' && result[2] == '?' && result[3] == '\\')
        {
            return result.ToString().Substring(4); // "\\?\" remove
        }
        else
        {
            return result.ToString();
        }
     }