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

发布于 2024-07-06 06:15:39 字数 795 浏览 10 评论 0原文

我有一个用 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。

I have an exe file generated with py2exe. In the setup.py I specify an icon to be embedded in the exe:

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

I tried loading the icon using:

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

But this produces an (very unspecific) error:
pywintypes.error: (0, 'LoadImage', 'No error message is available')

If I try specifying 0 as a string

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

then I get the error:
pywintypes.error: (1813, 'LoadImage', 'The specified resource type cannot be found in the image file.')

So, what's the correct method/syntax to load the icon?
Also please notice that I don't use any GUI toolkit - just the Windows API via PyWin32.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

冰葑 2024-07-13 06:15:40

如果您使用 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)

If you're using wxPython, you can use the following simple code:

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

I usually have code that checks whether it's running from an EXE or not, and acts accordingly:

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)
时常饿 2024-07-13 06:15:40

好吧,好吧...我安装了 py2exe,我认为这是一个错误。 在 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。 :)

Well, well... I installed py2exe and I think it's a bug. In py2exe_util.c they should init rt_icon_id to 1 instead of 0. The way it is now, it's impossible to load the first format of the first icon using LoadIcon/LoadImage.

I'll notify the developers about this if it's not already a known issue.

A workaround, in the meantime, would be to include the same icon twice in your setup.py:

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

You can load the second one, while Windows will use the first one as the shell icon. Remember to use non-zero IDs though. :)

陌上芳菲 2024-07-13 06:15:40

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

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

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

You should set the icon ID to something other than 0:

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

Windows resource IDs must be between 1 and 32767.

久而酒知 2024-07-13 06:15:39

@efotinis:你是对的。

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

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

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

如果你想创建一个指定大小的图标(因为 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)

@efotinis: You're right.

Here is a workaround until py2exe gets fixed and you don't want to include the same icon twice:

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

Be aware that 1 is not the ID you gave the icon in setup.py (which is the icon group ID), but the resource ID automatically assigned by py2exe to each icon in each icon group. At least that's how I understand it.

If you want to create an icon with a specified size (as CreateIconFromResource uses the system default icon size), you need to use CreateIconFromResourceEx, which isn't available 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)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文