pythonwinapiwin32gui

Python extracting a high resolution icon from an EXE file


I'm trying to extract .ico files from executable files i found this code on the website

import win32ui
import win32gui
import win32con
import win32api

ico_x = win32api.GetSystemMetrics(win32con.SM_CXICON)
ico_y = win32api.GetSystemMetrics(win32con.SM_CYICON)

large, small = win32gui.ExtractIconEx(r"C:\z\NEW ICON\a.exe",0)
win32gui.DestroyIcon(small[0])

hdc = win32ui.CreateDCFromHandle( win32gui.GetDC(0) )
hbmp = win32ui.CreateBitmap()
hbmp.CreateCompatibleBitmap( hdc, ico_x, ico_x )
hdc = hdc.CreateCompatibleDC()

hdc.SelectObject( hbmp )
hdc.DrawIcon( (0,0), large[0] )

hbmp.SaveBitmapFile( hdc, 'icon.bmp') 
 

this does work but it always gives me a 32x32 icon and i know the exe file contains higher resolution icons since i opened it with 7zip


Solution

  • To extract the largest icon you should iterate through ALL icons and find the largest:

    import os
    import win32ui
    import win32gui
    import win32con
    import win32api
    import ctypes
    
    lib = ctypes.windll.user32
    
    def save_icon(icon_handle, size, save_path):
        hdc = win32ui.CreateDCFromHandle(win32gui.GetDC(0))
        hbmp = win32ui.CreateBitmap()
        hbmp.CreateCompatibleBitmap(hdc, size, size)
        hdc = hdc.CreateCompatibleDC()
        hdc.SelectObject(hbmp)
        hdc.DrawIcon((0, 0), icon_handle)
        hbmp.SaveBitmapFile(hdc, save_path)
    
    def extract_largest_icon(exe_path, output_file):
        large_icons,small_icons = win32gui.ExtractIconEx(exe_path, 0, 50)
        
        all_icons =large_icons+ small_icons
    
        if not all_icons:
            print("No iconsss found in executable")
            return
    
        largest_icon = None
        largest_size= 0
        for icon in all_icons:
            icon_info = win32gui.GetIconInfo(icon)
            icon_width =lib.GetSystemMetrics(win32con.SM_CXICON)
            icon_height = lib.GetSystemMetrics(win32con.SM_CYICON)
            
            icon_size = icon_width * icon_height
            if icon_size > largest_size:
                largest_size = icon_size
                largest_icon = icon
    
        if largest_icon:
            print(f"Saving largest icon..")
            save_icon(largest_icon, win32api.GetSystemMetrics(win32con.SM_CXICON),output_file)
            win32gui.DestroyIcon(largest_icon)
    
    exe_file = r"C:\z\NEW ICON\a.exe"
    output_file = r"C:\path\to\output\icon_largest.bmp"
    
    extract_largest_icon(exe_file, output_file)