Come si fa a caricare un icona incorporata da un file exe con PyWin32?
Domanda
Ho un file exe generato con py2exe.Nel setup.py specificare un'icona per essere incorporato in un file exe:
windows=[{'script': 'my_script.py','icon_resources': [(0, 'my_icon.ico')], ...
Ho cercato di caricarli l'icona con:
hinst = win32api.GetModuleHandle(None)
hicon = win32gui.LoadImage(hinst, 0, win32con.IMAGE_ICON, 0, 0, win32con.LR_DEFAULTSIZE)
Ma questo produce un (molto vaghi) errore:
pywintypes.errore:(0, 'LoadImage', 'Nessun messaggio di errore è disponibile')
Se cerco di specificare 0 come una stringa
hicon = win32gui.LoadImage(hinst, '0', win32con.IMAGE_ICON, 0, 0, win32con.LR_DEFAULTSIZE)
poi ricevo l'errore:
pywintypes.errore:(1813, 'LoadImage', 'specificato tipo di risorsa può essere trovato nel file immagine.')
Allora, qual è il metodo corretto/sintassi per caricare l'icona?
Inoltre si prega di notare che io non uso nessuna GUI toolkit - API di Windows tramite PyWin32.
Soluzione
@efotinis:Hai ragione.
Qui è una soluzione fino a quando py2exe viene fissato e non si desidera includere la stessa icona due volte:
hicon = win32gui.CreateIconFromResource(win32api.LoadResource(None, win32con.RT_ICON, 1), True)
Essere consapevoli del fatto che 1 non è l'ID che ha dato l'icona in setup.py (che è l'icona ID gruppo), ma l'ID di risorsa automaticamente ricevuto da py2exe per ogni icona in ogni gruppo di icona.Almeno questo è quanto ho capito.
Se si desidera creare un'icona con una dimensione specificata (come CreateIconFromResource utilizza il sistema di default la dimensione delle icone), è necessario utilizzare CreateIconFromResourceEx, che non è disponibile via PyWin32:
icon_res = win32api.LoadResource(None, win32con.RT_ICON, 1)
hicon = ctypes.windll.user32.CreateIconFromResourceEx(icon_res, len(icon_res), True,
0x00030000, 16, 16, win32con.LR_DEFAULTCOLOR)
Altri suggerimenti
Se si utilizza wxPython, è possibile utilizzare il seguente codice:
wx.Icon(sys.argv[0], wx.BITMAP_TYPE_ICO)
Di solito ho il codice che controlla se è in esecuzione da un file EXE o non, e agisce di conseguenza:
def get_app_icon():
if hasattr(sys, "frozen") and getattr(sys, "frozen") == "windows_exe":
return wx.Icon(sys.argv[0], wx.BITMAP_TYPE_ICO)
else:
return wx.Icon("gfx/myapp.ico", wx.BITMAP_TYPE_ICO)
Bene, bene...Ho installato py2exe e penso che sia un bug.In py2exe_util.c dovrebbero init rt_icon_id
a 1 invece di 0.Il modo in cui è ora, è impossibile caricare il primo formato della prima icona con LoadIcon/LoadImage.
Io notificare gli sviluppatori su questo, se non è già un problema noto.
Una soluzione, nel frattempo, potrebbe essere quella di includere la stessa icona due volte nell'setup.py:
'icon_resources': [(1, 'my_icon.ico'), (2, 'my_icon.ico')]
È possibile caricare il secondo, mentre Windows di usare la prima come icona della shell.Ricordate di usare non-zero Id però.:)
Si dovrebbe impostare l'icona ID a qualcosa di diverso da 0:
'icon_resources': [(42, 'my_icon.ico')]
Windows resource IDs deve essere compreso tra 1 e 32767.