Как извлечь 128×128 растровые данные значка из EXE в python

Я пытаюсь извлечь значки из .exe-файлов в windows, используя win32gui. Я нашел функции ExtractIconEx () и ExtractIcon ().

Я могу получить значки размером 32×32 или 16×16 только из вышеперечисленных функций. следующая ссылка отвечает только на получение 32×32 изображений. Как извлечь 32×32 значки из растровых данных из EXE и преобразовать их в объект изображения PIL?

Мне нужно извлечь значки размером 128×128 или выше. Все идеи о том, как извлечь иконки большего размера из exe-файлов?

  • Почему я не могу найти документацию / ресурсы pywin32
  • Использование памяти в Windows с помощью Python
  • ImportError: нет модуля с именем pywintypes
  • Как читать jpg или png из буфера обмена Windows в python и наоборот?
  • Не удается загрузить библиотеку pywin32 win32gui
  • Чтение табличного контура в верхнем и нижнем колонтитуле в файле MS-Word с использованием Python
  • Получение ActivePython для работы с WSH
  • Установка цвета ячейки RGB для ячейки с pywin32 в excel?
  • 2 Solutions collect form web for “Как извлечь 128×128 растровые данные значка из EXE в python”

    Я сделал несколько исследований, а также опубликовал их. Если вы хотите просто увидеть код результата (я надеюсь, что это именно то, что вы просите), вы можете найти его после «горизонтального правила» ниже.

    Сначала я попытался использовать следующий код, чтобы определить, какие размеры значков хранятся в ресурсах файла:

    # Using LoadLibrary (rather than CreateFile) is required otherwise # LoadResource, FindResource and others will fail PATH = ... # Valid file path hlib = win32api.LoadLibrary(PATH) # This loop should print sizes of resources icons icon_names = win32api.EnumResourceNames(hlib, win32con.RT_ICON) for icon_name in icon_names: rec = win32api.LoadResource(hlib, win32con.RT_ICON, icon_name) hicon = win32gui.CreateIconFromResource(rec, True) info = win32gui.GetIconInfo(hicon) bminfo = win32gui.GetObject(info[3]) print("%2d: 0x%08X -> %d %d " % (icon_name, hicon, bminfo.bmWidth, bminfo.bmHeight)) 

    Хотя файл содержит только значки 16×16 и 32×32 пикселей, все будет хорошо, вот вывод для калькулятора Windows XP:

      1: 0x0093051B -> 32 32 2: 0x005B0513 -> 32 32 3: 0x007004CB -> 32 32 4: 0x002E04C9 -> 32 32 5: 0x033A04C5 -> 32 32 6: 0x00780487 -> 32 32 7: 0x0052045D -> 32 32 8: 0x055D053D -> 32 32 

    Как только я попытался использовать файл с большим значком, я получаю исключение:

     Traceback (most recent call last): File "extract_icon.py", line 50, in <module> hicon = win32gui.CreateIconFromResource(rec, True) pywintypes.error: (0, 'CreateIconFromResource', 'No error message is available') 

    После некоторых исследований я понял, что большой значок хранится не в формате ico , а в png (для моего случая).

    Конечно, я не знаю, что именно ваш .exe файл (это внутренности), но после того, как я проанализировал несколько файлов .exe которые я нашел на своем компьютере, я обнаружил, что значки размером более 32×32 или 16×16 пикселей, скорее всего, представлены в виде файлов .png (вы можете проверить его, используя, например, PE Explorer , пробная версия).

    Итак, чтобы прочитать изображение из ресурсов, я использовал руководство на C ++. Основная цель здесь – получить указатель на реальные данные ресурса изображения и скопировать его в буфер Python. И шаг завершения – сохранить его в файле (я думаю, вы могли бы перевести его в PIL самостоятельно).


    ПОЛНЫЙ КОД, ЧТОБЫ ПРОЧИТАТЬ БОЛЬШОЙ РЕСУРС :

     # Use wchar_t function version (FindResourceW rather than FindResourceA) from __future__ import unicode_literals # pywin32 imports import pywintypes import win32ui import win32gui import win32con import win32api import win32file # ctypes configuring. pywin32 has no a lot of required functions import ctypes import ctypes.util # memcpy used to copy data from resource storage to our buffer libc = ctypes.CDLL(ctypes.util.find_library('c')) libc.memcpy.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_size_t] libc.memcpy.restype = ctypes.c_char_p # All Windows backslashes must be escaped to LoadLibrary worked correctly '\' -> '\\' PATH = ... # WARNING: Assumed that icon_name - VALID resource ID # It can be determined in loop when enumerating resources: # if exception at CreateIconFromResource raised than this code appropriate # otherwise resource is standard icon and first code snippet can be used. # If resources Id exactly known then it can be hardcoded as in this code icon_name = 1 try: hlib = win32api.LoadLibrary(PATH) # This part almost identical to C++ hResInfo = ctypes.windll.kernel32.FindResourceW(hlib, icon_name, win32con.RT_ICON) size = ctypes.windll.kernel32.SizeofResource(hlib, hResInfo) rec = win32api.LoadResource(hlib, win32con.RT_ICON, icon_name) mem_pointer = ctypes.windll.kernel32.LockResource(rec) # And this is some differ (copy data to Python buffer) binary_data = (ctypes.c_ubyte * size)() libc.memcpy(binary_data, mem_pointer, size) # Save it with open("icon.png", "wb") as test_file: test_file.write(bytearray(binary_data)) except pywintypes.error as error: print "ERROR: %s" % error.strerror raise 

    ОБНОВЛЕНО :

    Код для автоматического поиска ресурсов без значков и извлечения его в файл с именем «Resource_XX»:

     # Same IMPORT's as previously should be used # All Windows backslashes must be escaped to LoadLibrary worked correctly '\' -> '\\' PATH = ... def extract(rec): try: hicon = win32gui.CreateIconFromResource(rec, True) except pywintypes.error as error: # Check on appropriate error if error.winerror != 6: raise print("Resource %2d isn't .ico, extract" % icon_name) # This part almost identical to C++ hResInfo = ctypes.windll.kernel32.FindResourceW(hlib, icon_name, win32con.RT_ICON) size = ctypes.windll.kernel32.SizeofResource(hlib, hResInfo) mem_pointer = ctypes.windll.kernel32.LockResource(rec) # And this is some differ (copy data to Python buffer) binary_data = (ctypes.c_ubyte * size)() libc.memcpy(binary_data, mem_pointer, size) # Save it with open("Resource_%s.png" % icon_name, "wb") as extract_file: extract_file.write(bytearray(binary_data)) else: info = win32gui.GetIconInfo(hicon) bminfo = win32gui.GetObject(info[3]) print("Resource %2d is .ico: 0x%08X -> %d %d " % (icon_name, hicon, bminfo.bmWidth, bminfo.bmHeight)) try: hlib = win32api.LoadLibrary(PATH) icon_names = win32api.EnumResourceNames(hlib, win32con.RT_ICON) for icon_name in icon_names: rec = win32api.LoadResource(hlib, win32con.RT_ICON, icon_name) extract(rec) except pywintypes.error as error: print "ERROR: %s" % error.strerror raise 

    Я хочу извлечь значок по умолчанию и различные параметры. На основе ответа Алексея и ответа Audionautics в потоке 32×32, вот код.

     # Use wchar_t function version (FindResourceW rather than FindResourceA) from __future__ import unicode_literals # pywin32 imports import win32con import win32api import win32file import win32gui import win32ui import pywintypes # ctypes configuring. pywin32 has no a lot of required functions import ctypes import ctypes.util # memcpy used to copy data from resource storage to our buffer libc = ctypes.CDLL(ctypes.util.find_library('c')) libc.memcpy.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_size_t] libc.memcpy.restype = ctypes.c_char_p # patch FindResourceW, ctypes.windll.kernel32.SizeofResource FindResourceW = ctypes.windll.kernel32.FindResourceW FindResourceW.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p] FindResourceW.restype = ctypes.c_void_p SizeofResource = ctypes.windll.kernel32.SizeofResource SizeofResource.argtypes = [ctypes.c_void_p, ctypes.c_void_p] SizeofResource.restype = ctypes.c_size_t # Using LoadLibrary (rather than CreateFile) is required otherwise # LoadResource, FindResource and others will fail PATH = "C:\\Program Files\\Internet Explorer\\iexplore.exe" hlib = win32api.LoadLibraryEx(PATH, 0, 2) # get icon groups, default is the first group icon_groups = win32api.EnumResourceNames(hlib, win32con.RT_GROUP_ICON) group_name = icon_groups[0] print group_name hRes = win32api.LoadResource(hlib, win32con.RT_GROUP_ICON, group_name) mem_icon_dir = ctypes.windll.kernel32.LockResource(hRes) # 32 bits color; 16 and 256 colors are too old # iterate through the common sizes icon_sizes = (16, 24, 32, 48, 96, 256) for icon_size in icon_sizes: icon_name = ctypes.windll.user32.LookupIconIdFromDirectoryEx(mem_icon_dir, True, icon_size, icon_size, 0x00000000); hResInfo = FindResourceW(hlib, icon_name, win32con.RT_ICON) size = ctypes.windll.kernel32.SizeofResource(hlib, hResInfo) rec = win32api.LoadResource(hlib, win32con.RT_ICON, icon_name) mem_icon = ctypes.windll.kernel32.LockResource(rec) # And this is some differ (copy data to Python buffer) binary_data = (ctypes.c_ubyte * size)() libc.memcpy(binary_data, mem_icon, size) hIconRet = ctypes.windll.user32.CreateIconFromResourceEx(binary_data, size, True, 0x00030000, 0, 0, 0x00000000); info = win32gui.GetIconInfo(hIconRet) bminfo = win32gui.GetObject(info[4]) # generate bitmap by drawing the icon hdc = win32ui.CreateDCFromHandle(win32gui.GetDC(0)) hbmp = win32ui.CreateBitmap() hbmp.CreateCompatibleBitmap(hdc, bminfo.bmWidth, bminfo.bmHeight) hcdc = hdc.CreateCompatibleDC() hcdc.SelectObject(hbmp) win32gui.DrawIconEx(hcdc.GetHandleOutput(), 0, 0, hIconRet, bminfo.bmWidth, bminfo.bmHeight, 0, 0, 0x0003) hbmp.SaveBitmapFile(hcdc, "icon-%03dx%03d-%05d-%03d.bmp" % (bminfo.bmWidth, bminfo.bmHeight, group_name, icon_name)) win32gui.DestroyIcon(hIconRet) 
    Python - лучший язык программирования в мире.