2

I try to extract the icon of file and return it to GetIconLocation of shell extension. in general I change the icons of files (te.docx.xx) with the extension of xx and returns the icon of file without the xx. (for this I cretae temp file in temp directory with the original extension e.g te.docx) my operating system is windows 7 x64. my code is:

    STDMETHODIMP CTxtIconShlExt::GetIconLocation (
    UINT uFlags,  LPTSTR szIconFile, UINT cchMax,
    int* piIndex, UINT* pwFlags )
{
DWORD     dwFileSizeLo, dwFileSizeHi;
DWORDLONG qwSize;
HANDLE    hFile;
OutputDebugStringW(L"Hello world, from GetIconLocation !");
    std::string strFilePath;
    std::string tempFolder="c:\\.tmp";
    std::string tempFile="tmpfile";
    std::string fileWithOutDN;
    SHFILEINFO retShFileInfo;
    for(int i = 0; m_szFilename[i] != 0; i++)
    {
        strFilePath += m_szFilename[i];
        }

    fileWithOutDN= strFilePath.substr(0,strFilePath.size()-3 );
    std::string extension = fileWithOutDN.substr(fileWithOutDN.find_last_of("."));
    CreateDirectory(tempFolder.c_str(),NULL);

    tempFile=tempFolder+"\\"+tempFile+extension;

    GetFileAttributes(tempFile.c_str()); // from winbase.h
    if(INVALID_FILE_ATTRIBUTES == GetFileAttributes(tempFile.c_str()) && GetLastError()==ERROR_FILE_NOT_FOUND)
    {
        //File not found
        HANDLE h = CreateFile(tempFile.c_str(),    // name of the file
                          GENERIC_WRITE, // open for writing
                          0,             // sharing mode, none in this case
                          0,             // use default security descriptor
                          CREATE_ALWAYS, // overwrite if exists
                          FILE_ATTRIBUTE_NORMAL,
                          0);
        if (h)
        {
             CloseHandle(h);
        }else
        {
            return S_FALSE; //faild to create file
        }
    }

    ZeroMemory(&retShFileInfo, sizeof(SHFILEINFO));
    CoInitialize(NULL);
    SHGetFileInfo(tempFile.c_str(),256,&retShFileInfo,sizeof(SHFILEINFO),SHGFI_ICON | SHGFI_LARGEICON);
    lstrcpyn ( szIconFile, retShFileInfo.szDisplayName, cchMax );
    *piIndex = retShFileInfo.iIcon;
    *pwFlags = 0;
    return S_OK;

my problem is that the retShFileInfo.szDisplayName return an empty array (all items are zero), it should return full path to icon location. I try to play with the combination of the flags but nothing was helpful

Beno
  • 721
  • 1
  • 10
  • 32
  • You have to use the `SHGFI_ICONLOCATION` flag to get the icon location. Also, `CreateFile()` returns `INVALID_HANDLE_VALUE` on failure, which is -1 and not 0 (and so you're incorrectly testing for failure). – Jonathan Potter Aug 19 '13 at 08:09
  • Thanks, but it didn't help. I still get retShFileInfo.szDisplayName as empty array (I can't see any path there) – Beno Aug 19 '13 at 08:20
  • Does `.tmp` even have an icon on your system? If it doesn't it will use the default file icon, and I don't think you'll get anything back in that case. Try `.txt` instead. – Jonathan Potter Aug 19 '13 at 08:31
  • SHGetFileInfo() returns an error code that you are not checking for failure. What value is it actually returning? – Remy Lebeau Aug 19 '13 at 08:40
  • .tmp is just the name of folder. the tempFile is equal to : C:\.tmp\tmpfile.docx – Beno Aug 19 '13 at 08:43
  • If you use the SHGFI_USEFILEATTRIBUTES flag, then you don't need to create a temp file at all, just give it a filename with the desired extension and it will return info about the default icon for that extension. – Remy Lebeau Aug 19 '13 at 08:47
  • I get return value = 1 – Beno Aug 19 '13 at 08:48
  • You might be interested in the [answer I got here](http://stackoverflow.com/questions/42676256/i-cant-get-shgetfileinfo-to-return-an-icon-location) when I had the same problem. – Felix Dombek Mar 08 '17 at 17:08
  • Possible duplicate of [I can't get SHGetFileInfo to return an icon location](http://stackoverflow.com/questions/42676256/i-cant-get-shgetfileinfo-to-return-an-icon-location) – Felix Dombek Mar 08 '17 at 22:00

0 Answers0