如何使用PyWin32从exe文件加载嵌入图标?

时间:2008-09-18 07:46:44

标签: python icons exe pywin32

我有一个用py2exe生成的exe文件。在setup.py中,我指定了一个嵌入exe:

的图标
windows=[{'script': 'my_script.py','icon_resources': [(0, 'my_icon.ico')], ...

我尝试使用以下方式加载图标:

hinst = win32api.GetModuleHandle(None)
hicon = win32gui.LoadImage(hinst, 0, win32con.IMAGE_ICON, 0, 0, win32con.LR_DEFAULTSIZE)

但这会产生(非常不明确的)错误:
pywintypes.error:(0,'LoadImage','没有错误消息可用')

如果我尝试将0指定为字符串

hicon = win32gui.LoadImage(hinst, '0', win32con.IMAGE_ICON, 0, 0, win32con.LR_DEFAULTSIZE)

然后我收到错误:
pywintypes.error:(1813,'LoadImage','在图像文件中找不到指定的资源类型。')

那么,加载图标的正确方法/语法是什么?
另请注意,我不使用任何GUI工具包 - 只是通过PyWin32的Windows API。

4 个答案:

答案 0 :(得分:5)

@efotinis:你是对的。

这是一个解决方法,直到py2exe得到修复,你不想两次包含相同的图标:

hicon = win32gui.CreateIconFromResource(win32api.LoadResource(None, win32con.RT_ICON, 1), True)

请注意, 1 不是您在setup.py中提供图标的ID(图标组ID),而是由py2exe自动分配的资源ID 到每个图标组中的每个图标。至少我就是这样理解的。

如果要创建具有指定大小的图标(因为CreateIconFromResource使用系统默认图标大小),则需要使用CreateIconFromResourceEx,这不是通过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)

答案 1 :(得分:1)

如果您正在使用wxPython,则可以使用以下简单代码:

wx.Icon(sys.argv[0], wx.BITMAP_TYPE_ICO)

我通常有代码检查它是否从EXE运行,并采取相应的行动:

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)

答案 2 :(得分:1)

嗯,好吧......我安装了py2exe,我认为这是一个bug。在py2exe_util.c中,它们应该从rt_icon_id初始化为1而不是0.现在的方式是,使用LoadIcon / LoadImage加载第一个图标的第一种格式是不可能的。

如果不是已知问题,我会通知开发者。

与此同时,解决方法是在setup.py中包含两次相同的图标:

'icon_resources': [(1, 'my_icon.ico'), (2, 'my_icon.ico')]

您可以加载第二个,而Windows将使用第一个作为shell图标。请记住使用非零ID。 :)

答案 3 :(得分:0)

您应该将图标ID设置为0以外的其他值:

'icon_resources': [(42, 'my_icon.ico')]

Windows资源ID必须介于1和32767之间。