IShellLink :: SetIconLocation translates my icon path to% Program Files%, which is WRONG

Does anyone know how to fix this behavior?

Currently, when our installer installs our application, he receives IShellLink , then downloads it with the data necessary for our shortcut (in the Start and Desktop menus), and then uses IPersistFile :: Save to write the shortcut.

The problem is that the path specified for the icon through IShellLink :: SetIconLocation is converted to using % ProgramFiles% ... , which ... for x64, is WRONG.

I noticed that many other 32-bit versions of the software do not work under x64, but I assumed that they themselves use % ProgamFiles% , as a literal element in their .lnk creation code. However, it looks like IShellLink is causing this error to exist. and I have no work (or perhaps the link properties editor in the shell is responsible for the problem and the base link is ok).

A few google searches didn’t find anything ... did anyone else come across this or know an article / example on how to make x64 windows not fool it?

Clarification Example:

hr = m_shell_link->SetIconLocation("C:\\Program Files (x86)\\Acme\\Prog.exe", 0);

A shortcut appears with the correct icon, but when you click "Change Icon" on the shortcut properties page, you will see the message "Windows cannot find the file% ProgramFiles% \ Acme \ Prog.exe." )

+3
3

, , .

        PWCHAR pIcon = L"C:\\Program Files (x86)\\Myfoo\\Bar.exe";
        DWORD dwLen = GetShortPathName(pIcon, NULL, 0);
        PWCHAR pShort = NULL; 
        if (dwLen) {
            pShort = new WCHAR[dwLen];
            dwLen = GetShortPathName(pIcon, pShort, dwLen);
            if (!dwLen) {
                delete [] pShort;
                pShort = NULL;
            }
        }

        if (NULL == pShort) {
            psl->SetIconLocation(pIcon,iTmp);
        } else {
            psl->SetIconLocation(pShort,iTmp);
        }
        delete [] pShort;
+3

"pointoforder" GitHub, , SLDF_HAS_EXP_ICON_SZ EXP_SZ_ICON_SIG IShellLinkDataList. Delphi.

+2

#, StackOverflow.

, . , , , .

IShellLinkDataList Save(), :

#region IShellLinkDataList Interface
[ComImportAttribute()]
[GuidAttribute("45e2b4ae-b1c3-11d0-b92f-00a0c90312e1")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
private interface IShellLinkDataList
{
    void AddDataBlock(IntPtr pDataBlock);
    void CopyDataBlock(uint dwSig, out IntPtr ppDataBlock);
    void RemoveDataBlock(uint dwSig);
    void GetFlags(out uint pdwFlags);
    void SetFlags(uint dwFlags);
}
#endregion

private const uint SLDF_HAS_EXP_ICON_SZ = 0x00004000;
private const uint EXP_SZ_ICON_SIG = 0xA0000007;

public void Save(string linkFile)
{   
    // Save the object to disk
    uint flags;
    if (linkA == null)
    {
        ((IShellLinkDataList)linkW).GetFlags(out flags);
        flags = flags & ~SLDF_HAS_EXP_ICON_SZ;
        ((IShellLinkDataList)linkW).SetFlags(flags);
        ((IShellLinkDataList)linkW).RemoveDataBlock(EXP_SZ_ICON_SIG);
        ((IPersistFile)linkW).Save(linkFile, true);
        shortcutFile = linkFile;
    }
    else
    {
        ((IShellLinkDataList)linkA).GetFlags(out flags);
        flags = flags & ~SLDF_HAS_EXP_ICON_SZ;
        ((IShellLinkDataList)linkA).SetFlags(flags);
        ((IShellLinkDataList)linkA).RemoveDataBlock(EXP_SZ_ICON_SIG);
        ((IPersistFile)linkA).Save(linkFile, true);
        shortcutFile = linkFile;
    }
}
+1
source

Source: https://habr.com/ru/post/1748567/


All Articles