如何使用 Delphi 更改外部 EXE 文件的图标?

And*_*zej 1 delphi delphi-10.3-rio

我想使用 Delphi 更改以前生成的 EXE 文件的主图标。EXE 文件也是我使用 Delphi 生成的。但我希望用户能够更改其图标。

我尝试使用 UpdateResource 函数更改 RT_GROUP_ICON 和 RT_ICON 没有成功:

procedure UpdateExeIcon(Const IconFilename, ExternalExeFilename:string);
var
  Stream     : TFileStream;
  hDestRes   : THANDLE;
  lpData     : Pointer;
  cbData     : DWORD;
begin
  Stream := TFileStream.Create(IconFilename,fmOpenRead or fmShareDenyNone);
  try
    Stream.Seek(0, soFromBeginning);
    cbData:=Stream.Size;
    if cbData>0 then
    begin
      GetMem(lpData,cbData);
      try
        Stream.Read(lpData^, cbData);
        hDestRes:= BeginUpdateResource(PChar(ExternalExeFilename), False);
        if hDestRes <> 0 then
        begin
          //if UpdateResource(hDestRes, RT_ICON,PChar('1'),1033,lpData,cbData) then
          if UpdateResource(hDestRes, RT_GROUP_ICON,PChar('MAINICON'),1033,lpData,cbData) then
          begin
            if not EndUpdateResource(hDestRes,FALSE) then RaiseLastOSError;
          end else RaiseLastOSError;
        end else RaiseLastOSError;
      finally
        FreeMem(lpData);
      end;
    end;
  finally
    Stream.Free;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

Ami*_*ack 6

有多种错误:

  1. UpdateResource(hDestRes, RT_ICON,PChar('1'),1033,lpData,cbData)lpName两种方式的参数作品:PChar('1')会变成为文本,而MakeIntResource(1)会变成为一个数字。您想要后者,而不是前者。
  2. 对于资源类型,RT_ICON您必须提供实际的 Icon有效负载,而不是整个 Icon文件。现在你做后者,而不是前者。查看 Icon 文件的外观,然后查看资源仅具有的内容。
  3. 资源类型RT_GROUP_ICON“仅”是描述现有RT_ICON资源的索引,应根据更新的图标进行修补(除非宽度、高度、颜色、像素深度和有效负载长度都相同)。在这里填写文件内容毫无意义。

资源黑客:图标有效载荷

在上方,您会看到Resource Hacker显示我们要更新的资源的原始字节。128是十六进制的字节长度。

HxD 图标文件容器

上面你会看到HxD显示了一个完整的图标文件- 我选择了第一个图标有效负载所在的部分:从偏移量开始,26长度为128(均为十六进制)。两个字节序列匹配。

如果你做的一切(使用MakeIntResource(1)RT_ICON,并提供了图标文件的图像数据),那么你的罚款-它的工作对我罚款:我的EXE,然后显示在Windows的资源管理器的新图标(没有执行它,寿)。RT_GROUP_ICON也应该更新,因为我不确定它似乎没有影响的地方以及它何时突然成为问题。在十六进制编辑器中查看您的文件,在资源编辑器中查看您的 EXE 将使您更好地理解所有操作。进一步阅读: