I am able to extract a file's icon and save it using the script below, but the script saves the icons in grey (seems to be 4 bit color depth).
How can I save icons while preserving their original color depth?
using namespace std;
#include <iostream>
#include <string>
#include <fstream>
#include <windows.h>
#include "commctrl.h"
#pragma comment(lib, "comctl32.lib")
#include <olectl.h>
#pragma comment(lib, "oleaut32.lib")
HRESULT SaveIcon(HICON hIcon, PCTSTR path) {
// Create the IPicture intrface
PICTDESC desc = { sizeof(PICTDESC) };
desc.picType = PICTYPE_ICON;
desc.icon.hicon = hIcon;
IPicture* pPicture = 0;
HRESULT hr = OleCreatePictureIndirect(&desc, IID_IPicture, FALSE, (void**)& pPicture);
if (FAILED(hr)) return hr;
// Create a stream and save the image
IStream* pStream = 0;
CreateStreamOnHGlobal(0, TRUE, &pStream);
LONG cbSize = 0;
hr = pPicture->SaveAsFile(pStream, TRUE, &cbSize);
// Write the stream content to the file
if (!FAILED(hr)) {
HGLOBAL hBuf = 0;
GetHGlobalFromStream(pStream, &hBuf);
void* buffer = GlobalLock(hBuf);
HANDLE hFile = CreateFile(path, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0);
if (!hFile) hr = HRESULT_FROM_WIN32(GetLastError());
else {
DWORD written = 0;
WriteFile(hFile, buffer, cbSize, &written, 0);
CloseHandle(hFile);
}
GlobalUnlock(buffer);
}
// Cleanup
pStream->Release();
pPicture->Release();
return hr;
}
HICON GetIcon(PCTSTR pszFile)
{
SHFILEINFO sfi;
HIMAGELIST himl = reinterpret_cast<HIMAGELIST>(
SHGetFileInfo(pszFile, 0, &sfi, sizeof(sfi),
SHGFI_SYSICONINDEX));
if (himl) {
return ImageList_GetIcon(himl, sfi.iIcon, ILD_NORMAL);
}
else {
return NULL;
}
}
int main()
{
string fileBaseName = "appName";
wstring fileBaseNameWSTRING(fileBaseName.begin(), fileBaseName.end());
HICON hIcon = GetIcon((fileBaseNameWSTRING + L".lnk").c_str());
if (hIcon == NULL) {
cout << "GetIcon failed" << endl;
return 1;
}
else {
HRESULT hr = SaveIcon(hIcon, (L"temp\\" + fileBaseNameWSTRING + L".ico").c_str());
return hr;
}
}
The SaveIcon function was taken from this page: How can I save HICON to an .ico file?