【问题标题】:How to get the localized special folder name?如何获取本地化的特殊文件夹名称?
【发布时间】:2012-10-31 05:12:54
【问题描述】:

我使用SHGetFileInfo()GetDisplayNameOf() 来获取特殊文件夹的名称。

如果本地化操作系统更改设置“非 Unicode 程序的当前语言”,这些函数返回值“????????????”。

用户遇到的这种设置组合。

shell32 不完全兼容 unicode?​​p>

Shell32.STRRET STRRET;
STRRET.uType = (uint)Shell32.STRRET_TYPE.STRRET_WSTR;
if (Windows.S_OK != ishellfolder_parent.GetDisplayNameOf(ptr_pidllast, (uint)Shell32.SHGNO.SHGDN_NORMAL | (uint)Shell32.SHGNO.SHGDN_INFOLDER, out STRRET))
                return null;

StringBuilder sbuilder = new StringBuilder(260);
Shell32.StrRetToBuf(ref STRRET, ptr_pidllast, sbuilder, (uint)sbuilder.Capacity);

怎么了?

***稍后添加 另一个例子来证明我的问题:

public static partial class Program
{
    const Int32 CSIDL_DESKTOP = (0x0000);
    const uint SHGFI_DISPLAYNAME = 0x000000200;     // get display name
    const uint SHGFI_PIDL = 0x000000008;     // pszPath is a pidl

    [StructLayout(LayoutKind.Sequential)]
    public struct SHFILEINFO
    {
        public static int NAMESIZE = 80;
        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;
    };

    [DllImport("shell32.dll")]
    static extern IntPtr SHGetFileInfo(IntPtr pidl, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbFileInfo, uint uFlags);
    [DllImport("shell32.dll")]
    public static extern IntPtr SHCloneSpecialIDList(IntPtr hwnd, Int32 CSIDL, bool create);


    [STAThread]
    static void Main(string[] args)
    {
        IntPtr pidl = SHCloneSpecialIDList(IntPtr.Zero, CSIDL_DESKTOP, false);
        SHFILEINFO shfi = new SHFILEINFO();
        if (IntPtr.Zero != SHGetFileInfo(
                    pidl,
                    0,
                    ref shfi,
                    (uint)Marshal.SizeOf(typeof(SHFILEINFO)),
                    SHGFI_PIDL | SHGFI_DISPLAYNAME))
        {
            System.Windows.Forms.MessageBox.Show(shfi.szDisplayName);
        }

此代码不正确。某些情况下返回值错误,如上所述。 谁能帮我举个正确的代码示例,完全兼容 Unicode 并使用非默认系统设置?


谢谢大家!经过一番实验,找到了解决办法。我的错误在这里:

Shell32.StrRetToBuf(ref STRRET, ptr_pidllast, sbuilder, (uint)sbuilder.Capacity);

签名应该是:

[DllImport("shlwapi.dll", CharSet=CharSet.Unicode, EntryPoint="StrRetToBufW")]
public static extern Int32 StrRetToBufW( ...

【问题讨论】:

  • 尝试使用函数 SHGetFileInfoW 的 unicode 版本,然后 GetDisplayNameOf 应该返回 STRRET_WSTR 类型的 STRRET。
  • 感谢您的回复。这是我尝试的第一件事。但它不起作用。我检查了 Windows 7,8。我在帖子中添加了其中一个代码示例。
  • 你是如何测试的?您是否将字符串写入控制台?
  • Shell32 是您正在使用的库,还是您自己制作的包含 P/Invoke 签名的类?如果是后者,你能显示你正在使用的签名吗?
  • 与其在问题底部添加答案,不如将其发布为作为答案(您可以这样做)。然后,您可以(在适当的延迟后)将其标记为已接受的答案,这将使以后搜索的人更清楚地知道找到了答案。我注意到问题出在 P/Invoke 签名中,但不是您发布的签名之一,所以我们没有太多机会帮助您:-(

标签: c# winapi shell localization globalization


【解决方案1】:

有人问了同样的问题。您可以使用那里的代码示例。

How to get the actual (localized) folder names?

【讨论】:

  • 如果您认为该问题是重复的,您应该投票关闭该问题的链接,而不是将其作为答案发布(我相信您有足够的代表这样做 - 我认为您可以投票收于250以上)
  • 不,这对我来说不是一个选项:(该选项通常出现在哪里?
  • 啊,对不起。误读了常见问题 - 您可以关闭自己的问题,但不能关闭其他人。不过,作为评论仍然比作为答案更好。
  • 问题不重复,有明显区别。
猜你喜欢
  • 1970-01-01
  • 2017-01-03
  • 2021-12-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多