首页 > 解决方案 > Unicode filename generated when creating a fileshortcut with IShellLinkA and IPersistFile in Win32

问题描述

I have this function to create a file-shortcut in Win32 :

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

When I call it as bellow :

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);

It generate the specific short-cut file And then filename is as entered filename in argv[4] like this :

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

But the real filename in file properties is a unicode name :

⸱浢p

Even I used MultiByteToWideChar() to convert dest filename to WCHAR[] :

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

In this function I'm used of IShellLink and IPersistFile interfaces as fllowing :

// 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;
}

Any suggested?

标签: c++winapishortcut

解决方案


我知道了 :

因为我将IShellLinkA* psl;接口定义为ANSI并且我必须在下面的函数中使用 ofIID_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); 

推荐阅读