c# - 如何使用 .Net 获取符号链接(symbolic link)(或重解析点)的目标?

标签 c# .net ntfs symlink

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

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

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


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

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

最佳答案

基于提到 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);
        }
    }
}

关于c# - 如何使用 .Net 获取符号链接(symbolic link)(或重解析点)的目标?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2302416/

相关文章:

c# - OWIN/Katana 未处理的异常全局处理程序?

c# - 如何使用 C# 编码/解码视频?

c# - 如何将字符串 "brakemeup"转换为 char[stringlength] 数组?

.net - ASPX 错误页面上的 .NET 堆栈跟踪中的数字是多少?

c - 如何复制硬盘分区?

python - 文件夹上的备用数据流

c# - 使用 CefSharp 上传文件

c# - CaSTLe Windsor 处置命令

python - 尝试从Python 3获取MFT表

C# 接口(interface)的 Expression.Property