在 Win32 中使用 IShellLinkA 和 IPersistFile 创建文件快捷方式时生成的 Unicode 文件名

Unicode filename generated when creating a fileshortcut with IShellLinkA and IPersistFile in Win32

我有在 Win32 中创建文件快捷方式的功能:

// prototype
HRESULT CreateLink(LPCSTR lpszPathObj, LPCSTR lpszPathLink, LPCSTR lpszDesc);

当我这样称呼它时:

StrCpyA(dst_file, argv[2]);
StrCpyA(src_file, argv[4]);

// concat ".lnk" to destination path
StrCatA(dst_file, ".lnk");

HRESULT res = CreateLink(src_file, dst_file, LINK_DESC);

它生成特定的快捷方式文件然后文件名是在argv[4]中输入的文件名,像这样:

e.g. : file_shortcut.exe -src 1.bmp -dst 123

但是 文件属性 中的真实文件名是一个 unicode 名称 :

⸱浢p

即使我使用 MultiByteToWideChar() 将目标文件名转换为 WCHAR[] :

INT wch_size = MultiByteToWideChar(CP_UTF8, 0, lpszPathLink, -1, NULL, 0);
MultiByteToWideChar(CP_UTF8, 0, lpszPathLink, -1, wsz, wch_size); 

在这个函数中,我使用了 IShellLinkIPersistFile 接口如下:

// function implementation
HRESULT CreateLink(LPCSTR lpszPathObj, LPCSTR lpszPathLink, LPCSTR lpszDesc) 
{ 
    HRESULT hres; 
    IShellLinkA* psl; 

    // Get a pointer to the IShellLink interface. It is assumed that CoInitialize
    // has already been called.
    CoInitialize(NULL);

    hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl); 
    if (SUCCEEDED(hres)) 
    { 
        IPersistFile* ppf;

        // Set the path to the shortcut target and add the description. 
        psl->SetPath(lpszPathObj); 
        psl->SetDescription(lpszDesc); 

        // Query IShellLink for the IPersistFile interface, used for saving the 
        // shortcut in persistent storage. 
        hres = psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf); 

        if (SUCCEEDED(hres)) 
        { 
            WCHAR wsz[MAX_PATH] = {0}; 

            // Ensure that the string is Unicode.
            INT wch_size = MultiByteToWideChar(CP_UTF8, 0, lpszPathLink, -1, NULL, 0);
            MultiByteToWideChar(CP_UTF8, 0, lpszPathLink, -1, wsz, wch_size); 

            // Save the link by calling IPersistFile::Save. 
            hres = ppf->Save(wsz, TRUE); 
            ppf->Release(); 
        } 
        psl->Release(); 
    } 
    return hres;
}

有什么建议吗?

我知道了:

因为我将 IShellLinkA* psl; 接口定义为 ANSI 而且我必须在波纹管函数中使用 IID_IShellLinkA 而不是 IID_IShellLink :

// mismatch with IShellLinkA
hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl);

// correct way used of IID_IShellLinkA instead of IID_IShellLink
hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkA, (LPVOID*)&psl);