返回

在 C++ Shell API 中如何转换显示文件名与已解析文件名?

windows

在 C++ Shell API 中转换显示文件名与已解析文件名

简介

在 Windows Shell API 中,理解显示文件名和已解析文件名的概念至关重要。显示文件名是用户看到的友好名称,而已解析文件名是文件的实际位置。本文将深入探究如何在 C++ 中使用 Shell API 将显示文件名转换为已解析文件名,以及反之亦然。

从显示文件名获取已解析文件名

方法一:SHParseDisplayName 函数

SHParseDisplayName 函数是转换显示文件名到已解析文件名的常用方法。它接受一个显示文件名作为输入,并返回一个指向已解析文件名的指针。该函数的语法如下:

HRESULT SHParseDisplayName(
    LPCWSTR pszDisplayName, 
    LPBINDCTX pbc, 
    PWSTR pszString, 
    int cchString, 
    SFGAOF dwReservedFlags, 
    BOOL *pbIsFolder
);

其中,pszDisplayName 是显示文件名,pszString 是用于存储已解析文件名的缓冲区。

从已解析文件名获取显示文件名

方法一:SHGetPathFromIDList 函数

SHParseDisplayName 函数相对应,SHGetPathFromIDList 函数用于将已解析文件名转换为显示文件名。它接受一个已解析文件名作为输入,并返回一个指向显示文件名的指针。该函数的语法如下:

HRESULT SHGetPathFromIDList(
    LPCITEMIDLIST pidl, 
    LPWSTR pszPath
);

其中,pidl 是已解析文件名,pszPath 是用于存储显示文件名的缓冲区。

使用 Shell API 的注意事项

  • 已解析文件名可能很长,因此请确保为其分配足够的缓冲区空间。
  • 已解析文件名可能包含特殊字符,因此请在使用它们时进行转义。
  • Shell API 函数可以失败,因此请检查错误代码并相应地处理错误。

示例代码

以下是将显示文件名转换为已解析文件名的示例代码:

#include <windows.h>
#include <shlobj.h>

int main()
{
    // 显示文件名
    LPCTSTR displayName = TEXT("This PC\\Apple iPhone\\Internal Storage\\202212__\\IMG_3295.MOV");

    // 已解析文件名的缓冲区
    TCHAR parsedName[MAX_PATH];

    // 将显示文件名解析为已解析文件名
    HRESULT hr = SHParseDisplayName(displayName, NULL, parsedName, sizeof(parsedName), 0);

    if (SUCCEEDED(hr))
    {
        // 已解析文件名已成功获取
        printf("已解析文件名:%s\n", parsedName);
    }
    else
    {
        // 无法获取已解析文件名
        printf("无法解析显示文件名:%s\n", displayName);
    }

    return 0;
}

以下是将已解析文件名转换为显示文件名的示例代码:

#include <windows.h>
#include <shlobj.h>

int main()
{
    // 已解析文件名
    LPCTSTR parsedName = TEXT("{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\\\?\\usb#vid_05ac&pid_12a8&mi_00#7&1a2090a1&0&0000#{6ac27878-a6fa-4155-ba85-f98f491d4f33}\\SID-{10004,Internal Storage,64000000000}\\{00000250-0000-0000-5002-000000000000}\\{000002A2-0000-0000-A202-000000000000}");

    // 显示文件名的缓冲区
    TCHAR displayName[MAX_PATH];

    // 从已解析文件名获取显示文件名
    HRESULT hr = SHGetPathFromIDList(parsedName, displayName);

    if (SUCCEEDED(hr))
    {
        // 显示文件名已成功获取
        printf("显示文件名:%s\n", displayName);
    }
    else
    {
        // 无法获取显示文件名
        printf("无法获取已解析文件名:%s\n", parsedName);
    }

    return 0;
}

结论

通过使用 SHParseDisplayNameSHGetPathFromIDList 函数,可以轻松地在 C++ 中转换显示文件名与已解析文件名。理解这两个函数的用法对于有效使用 Shell API 和管理文件系统至关重要。

常见问题解答

  1. 为什么需要将显示文件名转换为已解析文件名?

    • 已解析文件名提供文件的实际位置,而显示文件名可能只是别名或快捷方式。
  2. 转换失败时如何处理?

    • 检查错误代码并相应地处理错误,例如显示错误消息或采取其他恢复措施。
  3. 转换过程是否会影响文件系统?

    • 转换过程本身不会更改文件系统,它只是检索已存在的文件的信息。
  4. 除了这里介绍的方法,还有其他转换方法吗?

    • 是的,还有一些第三方库和工具可以用来转换文件路径,但 Shell API 是 Windows 平台的推荐方法。
  5. 如何确保已解析文件名的准确性?

    • Shell API 通常会提供准确的已解析文件名,但对于符号链接或损坏的文件,可能需要进一步验证。