Pergunta

Eu tenho um arquivo exe gerado com py2exe. No setup.py I especificar um ícone para ser incorporado no exe:

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

Eu tentei carregar o ícone usando:

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

Mas isso produz um erro (muito inespecíficos):
pywintypes.error: (0, 'LoadImage', 'Nenhuma mensagem de erro está disponível')

Se eu tentar especificando 0 como uma string

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

então eu recebo o erro:
pywintypes.error: (1813, 'LoadImage', 'O tipo de recurso especificado não pode ser encontrado no arquivo de imagem')

Então, qual é o método / sintaxe correta para carregar o ícone?
Também Por favor note que eu não utilizar qualquer conjunto de ferramentas GUI -. Apenas a API do Windows via PyWin32

Foi útil?

Solução

@efotinis: Você está certo.

Aqui está uma solução alternativa até que py2exe fica fixo e você não deseja incluir o mesmo ícone duas vezes:

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

Esteja ciente de que 1 não é a ID que você deu o ícone no setup.py (que é o ID ícone do grupo), mas o ID do recurso automaticamente atribuído pela py2exe para cada ícone em cada grupo ícone. Pelo menos é assim que eu entendo.

Se você deseja criar um ícone com um tamanho especificado (como CreateIconFromResource usa o tamanho do ícone padrão do sistema), você precisa usar CreateIconFromResourceEx, que não está disponível através 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)

Outras dicas

Se você estiver usando wxPython, você pode usar o seguinte código simples:

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

Normalmente, eu tenho o código que verifica se ele está sendo executado a partir de um EXE ou não, e age em conformidade:

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)

Bem, bem ... Eu instalei py2exe e eu acho que é um bug. Em py2exe_util.c eles devem o init rt_icon_id a 1 em vez de 0. O jeito que está agora, é impossível para carregar o primeiro formato do primeiro ícone usando LoadIcon / LoadImage.

Vou notificar os desenvolvedores sobre isso se não é já um problema conhecido.

Uma solução, entretanto, seria incluir o mesmo ícone duas vezes em sua setup.py:

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

Você pode carregar o segundo, enquanto o Windows usará o primeiro como o ícone shell. Lembre-se de usar diferentes de zero IDs embora. :)

Você deve definir o ícone de ID para algo diferente de 0:

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

IDs de recursos do Windows deve estar entre 1 e 32767.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top