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
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
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
@ 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