如何在Windows上获取区分大小写的路径?

Rod*_*igo 31 .net c# filepath

我需要知道哪条是给定路径的真正路径.

例如:

真正的路径是:d:\ src\File.txt
用户给我:D:\ src\file.txt
我需要的结果是:d:\ src\File.txt

Bor*_*rja 17

你可以使用这个功能:

[DllImport("kernel32.dll", SetLastError=true, CharSet=CharSet.Auto)]
static extern uint GetLongPathName(string ShortPath, StringBuilder sb, int buffer);

[DllImport("kernel32.dll")]
static extern uint GetShortPathName(string longpath, StringBuilder sb, int buffer); 

protected static string GetWindowsPhysicalPath(string path)
{
        StringBuilder builder = new StringBuilder(255);

        // names with long extension can cause the short name to be actually larger than
        // the long name.
        GetShortPathName(path, builder, builder.Capacity);

        path = builder.ToString();

        uint result = GetLongPathName(path, builder, builder.Capacity);

        if (result > 0 && result < builder.Capacity)
        {
            //Success retrieved long file name
            builder[0] = char.ToLower(builder[0]);
            return builder.ToString(0, (int)result);
        }

        if (result > 0)
        {
            //Need more capacity in the buffer
            //specified in the result variable
            builder = new StringBuilder((int)result);
            result = GetLongPathName(path, builder, builder.Capacity);
            builder[0] = char.ToLower(builder[0]);
            return builder.ToString(0, (int)result);
        }

        return null;
}
Run Code Online (Sandbox Code Playgroud)

  • @HarryJohnston:我测试了它并且它不起作用,没有抛出/返回错误但GetShortPathName只是在指定的情况下返回长路径. (2认同)
  • 此方法并非在所有情况下都有效。还是有问题。 (2认同)

Ter*_*ver 8

作为一个老朋友,我总是为此目的使用FindFirstFile..Net翻译是:

Directory.GetFiles(Path.GetDirectoryName(userSuppliedName), Path.GetFileName(userSuppliedName)).FirstOrDefault();
Run Code Online (Sandbox Code Playgroud)

这只能获得路径文件名部分的正确大小,而不是整个路径.

JeffreyLWhitledge的评论提供了一个递归版本的链接,该版本可以(但不总是)解决完整路径.

  • 你真的试过这个吗?它对我来说根本不起作用.目录大小写仍然来自userSuppliedName.尝试了几个.NET版本,结果相同. (3认同)

Rob*_*rto 5

替代解决方案

这是一个适合我使用区分大小写的路径在 Windows 和服务器之间移动文件的解决方案。它沿着目录树走下去并用GetFileSystemEntries(). 如果路径的一部分无效(UNC 或文件夹名称),则它仅更正该点之前的路径,然后使用原始路径来查找找不到的路径。无论如何,希望这能节省其他人在处理同样问题时的时间。

private string GetCaseSensitivePath(string path)
{
    var root = Path.GetPathRoot(path);
    try
    {
        foreach (var name in path.Substring(root.Length).Split(Path.DirectorySeparatorChar))
            root = Directory.GetFileSystemEntries(root, name).First();
    }
    catch (Exception e)
    {
        // Log("Path not found: " + path);
        root += path.Substring(root.Length);
    }
    return root;
}
Run Code Online (Sandbox Code Playgroud)

  • 即使使用文件名大小写,也能很好地工作!+1 我建议使用 EnumerateFileSystemEntries 而不是 GetFileSystemEntries。 (2认同)