---
name: set_exe_icon
kind: function
lang: go
domain: infra
version: "1.0.0"
purity: impure
signature: "func SetExeIcon(exePath, icoPath string) error"
description: "Embebe un icono (.ico multi-tamaño) en un ejecutable PE Windows post-build. Implementacion Go pura sin dependencias externas (sin rcedit/wine/rsrc). Parsea el ICONDIR + ICONDIRENTRY del .ico, construye un IMAGE_RESOURCE_DIRECTORY tree con RT_ICON + RT_GROUP_ICON, y appendea una nueva seccion .rsrc al PE. Soporta PE32 y PE32+. No soporta exe que ya tienen recursos (retorna error)."
tags: [windows, pe, exe, icon, rcedit, post-build]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: "error_go_core"
imports: [bytes, encoding/binary, fmt, os]
params:
  - name: exePath
    desc: "ruta absoluta o relativa al .exe Windows a modificar (se sobreescribe in-place)"
  - name: icoPath
    desc: "ruta al archivo .ico con uno o mas tamaños de icono"
output: "nil si el icono se embebio correctamente; error si el .exe ya tiene recursos, no es PE valido, o el .ico es invalido"
tested: false
tests: []
test_file_path: ""
file_path: "functions/infra/set_exe_icon.go"
---

## Ejemplo

```go
err := infra.SetExeIcon("myapp.exe", "logo.ico")
if err != nil {
    log.Fatal(err)
}
```

## Notas

- Solo Go binaries cross-compiled a Windows que **no** tengan seccion `.rsrc` previa. La mayoria de binarios Go limpios no la tienen.
- Si el .exe ya tiene recursos (creado con `goversioninfo`, `rsrc`, MSVC, etc.), retorna error y no modifica el archivo.
- El checksum del PE se pone a 0 tras la modificacion (Windows lo ignora para .exe normales; firmas Authenticode quedarian invalidadas).
- Soporta multi-resolucion: si el .ico tiene 16x16, 32x32, 256x256... todos se embeben y Windows elige el mejor.
- El icono cambia tras refrescar la cache de iconos de Explorer (a veces requiere `ie4uinit -show` o reiniciar Explorer).
