如何获得实际的(本地化)文件夹名称? [重复] 如何获得实际的(本地化)文件夹名称? [重复]

2019-05-12 11:13发布

这个问题已经在这里有一个答案:

  • 功能用于获取本地化的路径? 2个回答

我在C#编写功能,在那里我需要列出指定目录中的所有文件/文件夹名称。 该功能运行在OS EN罚款,但是当我运行本地化OS(例如对于)应用德语,我仍然得到特殊文件夹(Program Files文件,而不是计划,我的最爱,而不是法沃里滕等)的英文名称。 我不认为Environment.GetFolderPath与Environment.SpecialFolder可以是任何帮助,因为它没有我想要的,即它是什么赋予了列举的特殊文件夹的完整路径正好相反,然而,我想给定的本地化名称路径。 我一直在使用的文件,SHFILEINFO试过,但没有用的。 任何想法,我怎样才能得到文件夹名称显示在OS?

Answer 1:

你可以用本地化显示名称SHGetFileInfo API:

    public  static string GetDisplayName(Environment.SpecialFolder specialFolder)
    {
        IntPtr pidl = IntPtr.Zero;
        try
        {
            HResult hr = SHGetFolderLocation(IntPtr.Zero, (int) specialFolder, IntPtr.Zero, 0, out pidl);
            if (hr.IsFailure)
                return null;

            SHFILEINFO shfi;
            if (0 != SHGetFileInfo(
                        pidl,
                        FILE_ATTRIBUTE_NORMAL,
                        out shfi,
                        (uint)Marshal.SizeOf(typeof(SHFILEINFO)),
                        SHGFI_PIDL | SHGFI_DISPLAYNAME))
            {
                return shfi.szDisplayName;
            }
            return null;
        }
        finally
        {
            if (pidl != IntPtr.Zero)
                ILFree(pidl);
        }
    }

    public static string GetDisplayName(string path)
    {
        SHFILEINFO shfi;
        if (0 != SHGetFileInfo(
                    path,
                    FILE_ATTRIBUTE_NORMAL,
                    out shfi,
                    (uint)Marshal.SizeOf(typeof(SHFILEINFO)),
                    SHGFI_DISPLAYNAME))
        {
            return shfi.szDisplayName;
        }
        return null;
    }

    private const uint FILE_ATTRIBUTE_NORMAL = 0x00000080;
    private const uint SHGFI_DISPLAYNAME = 0x000000200;     // get display name
    private const uint SHGFI_PIDL = 0x000000008;     // pszPath is a pidl

    [DllImport("shell32")]
    private static extern int SHGetFileInfo(IntPtr pidl, uint dwFileAttributes, out SHFILEINFO psfi, uint cbFileInfo, uint flags);
    [DllImport("shell32")]
    private static extern HResult SHGetFolderLocation(IntPtr hwnd, int nFolder, IntPtr token, int dwReserved, out IntPtr pidl);
    [DllImport("shell32")]
    private static extern void ILFree(IntPtr pidl);

    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
    private struct SHFILEINFO
    {
        public IntPtr hIcon;
        public int iIcon;
        public uint dwAttributes;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
        public string szDisplayName;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
        public string szTypeName;
    }

[StructLayout(LayoutKind.Sequential)]
public struct HResult
{
    private int _value;

    public int Value
    {
        get { return _value; }
    }

    public Exception Exception
    {
        get { return Marshal.GetExceptionForHR(_value); }
    }

    public bool IsSuccess
    {
        get { return _value >= 0; }
    }

    public bool IsFailure
    {
        get { return _value < 0; }
    }
}


Answer 2:

我没弄清楚如何得到这个工作。 不知道什么是错与上面的代码(我也得到了中国Unicode字符),但这似乎可靠地工作。 刚刚通过的路径(例如,通过调用:

GetDisplayName(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments));

并返回该文件夹的显示名称(在这个例子中,“我的文档”或任何您已重新命名它)。

using System.Runtime.InteropServices;
...
public const uint FILE_ATTRIBUTE_NORMAL = 0x00000080;
public const uint SHGFI_DISPLAYNAME = 0x000000200;     // get display name

[DllImport("shell32")]
public static extern int SHGetFileInfo(string pszPath, uint dwFileAttributes, 
    out SHFILEINFO psfi, uint cbFileInfo, uint flags);

[StructLayout(LayoutKind.Sequential)]
public struct SHFILEINFO
{
    public IntPtr hIcon;
    public IntPtr iIcon;
    public uint dwAttributes;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
    public string szDisplayName;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
    public string szTypeName;
};


public  static string GetDisplayName(string path)
{
    SHFILEINFO shfi = new SHFILEINFO();
    if (0 != SHGetFileInfo(path,FILE_ATTRIBUTE_NORMAL,out shfi,
        (uint)Marshal.SizeOf(typeof(SHFILEINFO)),SHGFI_DISPLAYNAME))
    {
        return shfi.szDisplayName;
    }
    return null;
}


Answer 3:

你必须要确保字符集设置为Unicode为的DllImport和StructLayout。

[DllImport("shell32", CharSet = CharSet.Unicode)]
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]


文章来源: How to get the actual (localized) folder names? [duplicate]