2014-04-24 15 views
6

Sto cercando di estrarre le icone da file .exe in Windows utilizzando win32gui. Ho trovato le funzionalità ExtractIconEx() e ExtractIcon().Come estrarre i dati di 128 x 128 icona bitmap da EXE in python

Sono in grado di ottenere icone di dimensioni 32x32 o 16x16 solo dalle funzionalità di cui sopra. il seguente link risponde solo a modo di estrarre immagini 32x32. How to extract 32x32 icon bitmap data from EXE and convert it into a PIL Image object?

Ho bisogno di estrarre icone di dimensione 128x128 o superiore. Qualche idea su come estrarre le icone di grandi dimensioni dai file exe?

risposta

8

Ho fatto alcune ricerche e anche pubblicato. Se desideri vedere solo il codice del risultato (spero che sia esattamente quello che chiedi), potresti trovarlo dopo la "regola orizzontale" di seguito.

Per prima cosa ho cercato di usare il codice successivo per determinare quali dimensioni delle icone memorizzato nelle risorse del file:

# 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)) 

Mentre file contiene solo 16x16 e 32x32 pixel icone di tutto sarà ok, qui l'uscita per Windows XP calcolatrice:

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 

Una volta ho provato in archivio con grande icona ho ottenere l'eccezione:

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') 

Dopo alcune ricerche ho scoperto che l'icona grande non è nel formato ico ma nel png (per il mio caso).

Naturalmente non so cosa esattamente il file .exe (è interni), ma dopo che ho analizzare i diversi file .exe che ho situati nel mio PC ho scoperto che le icone di grandi dimensioni di 32x32 o 16x16 pixel la maggior parte probabilmente rappresentato dai file .png (è possibile verificarlo utilizzando ad es. PE Explorer, versione di prova esistente).

Quindi, per leggere l'immagine dalle risorse, ho utilizzato lo guide in C++. L'obiettivo principale qui è quello di ottenere un puntatore ai dati reali della risorsa immagine e copiarli nel buffer Python. E il passo finale è salvarlo nel file (penso che potresti tradurlo in PIL da solo).


codice completo LEGGERE RISORSA GRANDE:

# 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 

AGGIORNATO:

Codice di cercare automaticamente risorse non icona ed estrarlo in file denominato " 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 
+0

ho provato l'impostazione del codice impostando PATH = "C: \ Programmi \ VideoLAN \ VLC \ VLC.exe " Restituisce immagini vuote, ho provato più file diversi Mi manca qualcosa? – sj7

+0

Ho provato su http://www.splashtop.com/ funziona per me. C'è qualche eccezione o solo file vuoto (potrebbe essere eseguito il backslash?) E sei sicuro di aver definito ID risorsa valido (nome_icona)? Provo ora VLC. Aggiornerò la risposta al più presto. – Alexei

+0

@ sj7 Ho provato che funziona per me su vlc: http : //get.videolan.org/vlc/2.1.3/win32/vlc-2.1.3-win32.zip In primo luogo ho bisogno di escape backslash (altrimenti LoadLibrary non ha funzionato) e la seconda risorsa giusta (icona png) ha id 3. 'PATH =" c: \\ vlc-2.1.3 \\ vlc.exe "' e 'icon_name = 3'. È quell'aiuto? – Alexei

1

Desidero estrarre l'icona predefinita e i diversi formati. Basato sulla risposta di Alexei e la risposta di Audionautics nel thread 32x32, ecco il codice.

# 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) 
Problemi correlati