Как загрузить встроенную иконку из exe-файла с помощью PyWin32?

StackOverflow https://stackoverflow.com/questions/90775

  •  01-07-2019
  •  | 
  •  

Вопрос

У меня есть exe-файл, сгенерированный с помощью py2exe.В setup.py Я указываю значок, который будет встроен в исполняемый файл:

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.ошибка:(0, 'Изображение загрузки', 'Сообщение об ошибке недоступно')

Если я попытаюсь указать 0 в виде строки

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

затем я получаю сообщение об ошибке:
pywintypes.ошибка:(1813, 'LoadImage', 'Указанный тип ресурса не может быть найден в файле изображения.')

Итак, каков правильный метод / синтаксис для загрузки значка?
Также, пожалуйста, обратите внимание, что я не использую никаких инструментов GUI - только Windows API через PyWin32.

Это было полезно?

Решение

@эфотинис:Ты прав.

Вот обходной путь, пока py2exe не будет исправлен, и вы не захотите включать один и тот же значок дважды:

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

Имейте в виду , что 1 это не идентификатор, который вы указали значку в setup.py (который является идентификатором группы значков), а идентификатор ресурса автоматически присваивается 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)

Другие советы

Если вы используете 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)

Так, так...Я установил py2exe и думаю, что это ошибка.В py2exe_util.c они должны инициализировать rt_icon_id к 1 вместо 0.В нынешнем виде невозможно загрузить первый формат первого значка с помощью LoadIcon / LoadImage.

Я уведомлю разработчиков об этом, если это еще не известная проблема.

В то же время обходным решением было бы дважды включить один и тот же значок в ваш setup.py:

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

Вы можете загрузить второй, в то время как Windows будет использовать первый в качестве значка оболочки.Однако не забудьте использовать ненулевые идентификаторы.:)

Вы должны установить для идентификатора значка значение, отличное от 0:

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

Идентификаторы ресурсов Windows должны быть в диапазоне от 1 до 32767.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top