humantrash
humantrash

Reputation: 85

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

Upvotes: 1

Views: 87

Answers (1)

Kirill Ilichev
Kirill Ilichev

Reputation: 1289

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)

Upvotes: 1

Related Questions