I've made some search and like you've guessed it is not as simple
as:
ChangeExeIcon "MyExe.exe", "MyIcon.ico" .....
The simplest I've found is in a Microsoft example and works differently
Basically, this code reads an Icon in a source Exe and replaces (or adds if doesnt exist) An Icon in a destination Exe:
#Constant RT_ICON 3
Load DLL "kernel32.dll", 1
SourceExeFile$ = "Source.exe"
DestExeFile$ = "Dest.exe"
SourceExeIconId = 1
DestExeIconId = 1
hExe = Call DLL(1, "LoadLibraryA", SourceExeFile$)
hRes = Call DLL(1, "FindResourceA", hExe, SourceExeIconId, RT_ICON)
hResLoad = Call DLL(1, "LoadResource", hExe, hRes)
lpResLock = Call DLL(1, "LockResource", hResLoad)
hUpdateRes = Call DLL(1, "BeginUpdateResourceA", DestExeFile$, 0)
SizeofResource = Call DLL(1, "SizeofResource", hExe, hRes)
r = Call DLL(1, "UpdateResourceA", hUpdateRes, RT_ICON, DestExeIconId, 0, lpResLock, SizeofResource)
r = Call DLL(1, "EndUpdateResourceA", hUpdateRes, 0)
r = Call DLL(1, "FreeLibrary", hExe)
Delete DLL 1
The icon are resources and have an Id number
the icons exist in several sizes, this code change only one
I used resourcehacker to read to check the ids in a dbp exe
http://www.angusj.com/resourcehacker/
Theorically, you have to check every result of the function calls
and abort if something is 0...
It seems that the icon change is not directly visible in the explorer. I first thought all had failed down,
but the change reveals after copy or rename the exe.. Dont know why.. maybe the old icons cached somewhere..
but I lack time to deepen this..