如何获取实际(本地化)文件夹名称?

我在c#中编写一个function,我需要列出给定目录中的所有文件/文件夹名称。 该function在EN OS上运行良好,但是当我在本地化操作系统(例如)德语上运行应用程序时,我仍然获得特殊文件夹的英文名称(程序文件而不是程序,collections夹而不是Favoriten等)。 我不认为带有Environment.SpecialFolder的Environment.GetFolderPath可以提供任何帮助,因为它与我想要的完全相反,即它给出了枚举的特殊文件夹的完整路径,而我想要给定的本地化名称路径。 我尝试过使用File,SHFileInfo,但没有用。 任何想法,我怎样才能获得操作系统中显示的文件夹名称?

您可以使用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; } } } 

我确实弄明白了如何让它发挥作用。 不确定上面的代码有什么问题(我也有中文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; } 

您必须确保将CharSet设置为DllImport和StructLayout的UniCode。

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