SetWorkingDir, %A_ScriptDir%

ExeFil := "444444.exe"
IcoFil := "9.ico"

ReplaceIcon(ExeFil, IcoFil) 

; https://www.autohotkey.com/boards/viewtopic.php?p=227708#p227708
; ============================================================================
ReplaceIcon(ExeFil, IcoFil) {
  Global _EI_HighestIconID
  Static IconID := 159

  Module := DllCall("BeginUpdateResource", "str", ExeFil, "uint", 0, "ptr")

  ids := EnumIcons(ExeFil, IconID)
  If !IsObject(ids)
    Return false

  f := FileOpen(IcoFil, "r")
  If !IsObject(f)
    Return false

  VarSetCapacity(igh, 8), f.RawRead(igh, 6)
  If (NumGet(igh, 0, "UShort") != 0) || (NumGet(igh, 2, "UShort") != 1)
    Return false

  wCount := NumGet(igh, 4, "UShort")

  VarSetCapacity(rsrcIconGroup, rsrcIconGroupSize := 6 + wCount*14)
  NumPut(NumGet(igh, "Int64"), rsrcIconGroup, "Int64") ; fast copy

  ige := &rsrcIconGroup + 6

  ; Delete all the images
  Loop, % ids.MaxIndex()
    DllCall("UpdateResource", "ptr", Module, "ptr", 3, "ptr", ids[A_Index], "ushort"
            , 0x409, "ptr", 0, "uint", 0, "uint")

  Loop, %wCount% {
    thisID := ids[A_Index]
    If !thisID
      thisID := ++ _EI_HighestIconID

    f.RawRead(ige+0, 12) ; read all but the offset
    NumPut(thisID, ige+12, "UShort")

    imgOffset := f.ReadUInt()
    oldPos := f.Pos
    f.Pos := imgOffset

    VarSetCapacity(iconData, iconDataSize := NumGet(ige+8, "UInt"))
    f.RawRead(iconData, iconDataSize)
    f.Pos := oldPos

    DllCall("UpdateResource", "ptr", Module, "ptr", 3, "ptr", thisID, "ushort"
            , 0x409, "ptr", &iconData, "uint", iconDataSize, "uint")

    ige += 14
  }

  DllCall("UpdateResource", "ptr", Module, "ptr", 14, "ptr", IconID, "ushort", 0x409, "ptr", &rsrcIconGroup, "uint", rsrcIconGroupSize, "uint")

  DllCall("EndUpdateResource", "ptr", Module, "uint", 0)
}

EnumIcons(ExeFil, IconID) {
  ; RT_GROUP_ICON = 14
  ; RT_ICON = 3
  Global _EI_HighestIconID
  Static pEnumFunc := RegisterCallback("EnumIcons_Enum")

  hModule := DllCall("LoadLibraryEx", "str", ExeFil, "ptr", 0, "ptr", 2, "ptr")
  If !hModule
    Return

  _EI_HighestIconID := 0
; ***
; If the following section is removed, ReplaceIcon() seems to work with
; EVERY executable (not only with AutoHotkex.exe or AutoHotkeySC.bin)!!!
; ======================================================================
/*
  If DllCall("EnumResourceNames", "ptr", hModule, "ptr", 3, "ptr", pEnumFunc, "uint", 0) = 0
  {
    DllCall("FreeLibrary", "ptr", hModule)
    Return
  }
*/

  hRsrc := DllCall("FindResource", "ptr", hModule, "ptr", IconID, "ptr", 14, "ptr")
  hMem := DllCall("LoadResource", "ptr", hModule, "ptr", hRsrc, "ptr")
  pDirHeader := DllCall("LockResource", "ptr", hMem, "ptr")
  pResDir := pDirHeader + 6

  wCount := NumGet(pDirHeader+4, "UShort")
  iconIDs := []

  Loop, %wCount% {
    pResDirEntry := pResDir + (A_Index-1)*14
    iconIDs[A_Index] := NumGet(pResDirEntry+12, "UShort")
  }

  DllCall("FreeLibrary", "ptr", hModule)
  Return iconIDs
}

EnumIcons_Enum(hModule, Type, Name, lParam) {
  Global _EI_HighestIconID
  If (Name < 0x10000) && (Name > _EI_HighestIconID)
   _EI_HighestIconID := Name
  Return 1
}

 

声明:站内资源为整理优化好的代码上传分享与学习研究,如果是开源代码基本都会标明出处,方便大家扩展学习路径。请不要恶意搬运,破坏站长辛苦整理维护的劳动成果。本站为爱好者分享站点,所有内容不作为商业行为。如若本站上传内容侵犯了原著者的合法权益,请联系我们进行删除下架。