aj3423
aj3423

Reputation: 2561

Failed to get exe icon with SHGetFileInfo

I'm using cmake + nmake to build exe, I want to get the icon handle from the executable itself.

CMakeLists.txt:

add_executable(test test.cpp test.rc)

test.rc:

IDI_ICON   ICON  DISCARDABLE  "test.ico"
IDI_ICON0   ICON  DISCARDABLE  "test.ico"
IDI_ICON1   ICON  DISCARDABLE  "test.ico"
IDI_ICON2   ICON  DISCARDABLE  "test.ico"

test.cpp:

#include <windows.h>
#include <iostream>
using namespace std;

int main() {
    SHFILEINFO  sfi;
    memset(&sfi, 0, sizeof(sfi));
    DWORD_PTR ret = ::SHGetFileInfo("g:/workspace/test2/debug/test.exe",
                    0, &sfi, sizeof(sfi), SHGFI_LARGEICON|SHGFI_SMALLICON|SHGFI_ICON);
    cout << hex;
    cout << ret << endl; // prints 0
    cout << sfi.hIcon << endl; // prints 0
}

The executable g:/workspace/test2/debug/test.exe does have icon, but the SHGetFileInfo failed to get the icon, what's wrong with the code?

Upvotes: 0

Views: 998

Answers (2)

Cyclonecode
Cyclonecode

Reputation: 30051

My best bet would be that you (as per the documentation) need to call CoInitialize() prior to trying to get extract the icon information. And if we have a windows function that can not handle forward slashes I would not be surprised:

You must initialize Component Object Model (COM) with CoInitialize or OleInitialize prior to calling SHGetFileInfo.

So, the code code be changed to something like:

int main() {
  SHFILEINFO  sfi;

  // initialize COM library
  CoInitialize(NULL);
  memset(&sfi, 0, sizeof(sfi));
  DWORD_PTR ret = ::SHGetFileInfo("g:/workspace/test2/debug/test.exe",
                0, &sfi, sizeof(sfi), SHGFI_LARGEICON | SHGFI_ICON);
  cout << hex;
  cout << ret << endl;
  cout << sfi.hIcon << endl;

  CoUninitialize();
}

Upvotes: 2

aj3423
aj3423

Reputation: 2561

As comment post by Jonathan Potter, it's caused by the back-slash. The code works after changing '/' to '\' in the file path.

Upvotes: 1

Related Questions