Как изменить значок внешнего EXE-файла, используя Delphi? - PullRequest
1 голос
/ 01 августа 2020

Я хочу изменить главный значок ранее созданного EXE-файла, используя Delphi. Файл 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;

1 Ответ

6 голосов
/ 01 августа 2020

Есть несколько ошибок:

  1. В UpdateResource(hDestRes, RT_ICON,PChar('1'),1033,lpData,cbData) параметр lpName работает двумя способами: PChar('1') будет отображаться как текст, а MakeIntResource(1) будет отображаться как число. Вам нужен последний вариант, а не первый.
  2. Для типа ресурса RT_ICON вы должны предоставить фактическую Icon полезную нагрузку , а не весь Icon файл . Прямо сейчас вы делаете второе, а не первое. Посмотрите, как выглядит файл значка, а затем посмотрите, что есть только у ресурса.
  3. Тип ресурса RT_GROUP_ICON - это «всего лишь» индекс, описывающий существующие RT_ICON ресурсы, и его следует исправить в соответствии с вашими обновленными Значок (если ширина, высота, цвета, глубина пикселей и длина полезной нагрузки не совпадают). Заполнение содержимого файла здесь никогда не имеет смысла.

Resource Hacker: icon payload

Above you see Resource Hacker отображение необработанных байтов ресурса, который мы хотим обновить. 128 - длина байтов в шестнадцатеричном формате.

HxD icon file container

Above you see HxD отображение всего значка файл - я выбрал часть, где находится первый значок полезная нагрузка находится: начиная со смещения 26 и имеет длину 128 (оба шестнадцатеричные). Обе последовательности байтов совпадают.

Если вы сделаете все это (используя MakeIntResource(1) на RT_ICON и предоставите только данные изображения файла значка), тогда все в порядке - у меня все сработало: мой EXE затем отобразил новый значок в Windows 'Проводнике (хотя и не выполнил его). Также следует обновить RT_GROUP_ICON, так как я не уверен, где это, кажется, не имеет никакого эффекта, и когда это внезапно становится проблемой. Просмотр ваших файлов в шестнадцатеричном редакторе и вашего EXE в редакторе ресурсов поможет вам лучше понять все действия. Дополнительные материалы для чтения:

  • Формат файла Icon (довольно просто)
  • Формат RT_GROUP_ICON (почти идентичен файлам Icon)
...