Delphi 在运行时更改应用程序的图标

Delphi 在运行时更改应用程序的图标,delphi,Delphi,我有一个带有特定图标的EXE(App1.EXE)文件,还有一个带有另一个特定图标的EXE(App2.EXE)文件 App2作为资源嵌入到App1项目中,但我想停止使用此资源,并将整个工作仅保留在App1.exe中。 但是,在执行App1.exe之后,我想将其保存在另一个文件中(复制到另一个文件),图标为App2.exe。。。我有App2.exe的.ico文件,这不是问题所在。但是,当我将App1.exe复制到另一个文件时,如何使其具有原始图标,以及另一个具有App2.exe图标的App1.exe

我有一个带有特定图标的EXE(App1.EXE)文件,还有一个带有另一个特定图标的EXE(App2.EXE)文件

App2作为资源嵌入到App1项目中,但我想停止使用此资源,并将整个工作仅保留在App1.exe中。
但是,在执行App1.exe之后,我想将其保存在另一个文件中(复制到另一个文件),图标为App2.exe。。。我有App2.exe的.ico文件,这不是问题所在。但是,当我将App1.exe复制到另一个文件时,如何使其具有原始图标,以及另一个具有App2.exe图标的App1.exe,这是否可以通过简单的代码实现?

我不确定是否完全理解您的要求 我认为您应该复制它,然后更改图标
此代码将从另一个exe文件更新exe图标

unit iconchanger;


interface

uses windows;

  type
    PICONDIRENTRYCOMMON = ^ICONDIRENTRYCOMMON;
    ICONDIRENTRYCOMMON = packed record
    bWidth             : Byte;  // Width, in pixels, of the image
    bHeight            : Byte;  // Height, in pixels, of the image
    bColorCount        : Byte;  // Number of colors in image (0 if >=8bpp)
    bReserved          : Byte;  // Reserved ( must be 0)
    wPlanes            : Word;  // Color Planes
    wBitCount          : Word;  // Bits per pixel
    dwBytesInRes       : DWord; // How many bytes in this resource?
    end;

    PICONDIRENTRY      = ^ICONDIRENTRY;
    ICONDIRENTRY       = packed record
    common             : ICONDIRENTRYCOMMON;
    dwImageOffset      : DWord; // Where in the file is this image?
    end;

    PICONDIR           = ^ICONDIR;
    ICONDIR            = packed record
    idReserved         : Word; // Reserved (must be 0)
    idType             : Word; // Resource Type (1 for icons)
    idCount            : Word; // How many images?
    idEntries          : ICONDIRENTRY; // An entry for each image (idCount of 'em)
    end;

    PGRPICONDIRENTRY   = ^GRPICONDIRENTRY;
    GRPICONDIRENTRY    = packed record
    common             : ICONDIRENTRYCOMMON;
    nID                : Word;  // the ID
    end;

    PGRPICONDIR        = ^GRPICONDIR;
    GRPICONDIR         = packed record
    idReserved         : Word; // Reserved (must be 0)
    idType             : Word; // Resource type (1 for icons)
    idCount            : Word; // How many images?
    idEntries          : GRPICONDIRENTRY;  // The entries for each image
    end;

function UpdateApplicationIcon(srcicon : PChar; destexe : PChar) : Boolean;

implementation

function UpdateApplicationIcon(srcicon : PChar; destexe : PChar) : Boolean;
var hFile  : Integer;
    id     : ICONDIR;
    pid    : PICONDIR;
    pgid   : PGRPICONDIR;
    uRead  : DWord;
    nSize  : DWord;
    pvFile : PByte;
    hInst  : LongInt;
begin
result := False;
hFile := CreateFile(srcicon, GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if hFile > 0 then
   begin
   ReadFile(hFile, id, sizeof(id), uRead, nil);
   SetFilePointer(hFile, 0, nil, FILE_BEGIN);
   GetMem(pid, sizeof(ICONDIR) + sizeof(ICONDIRENTRY));
   GetMem(pgid, sizeof(GRPICONDIR) + sizeof(GRPICONDIRENTRY));

   ReadFile(hFile, pid^, sizeof(ICONDIR) + sizeof(ICONDIRENTRY), uRead, nil);
   move(pid^, pgid^, sizeof(GRPICONDIR));

   pgid^.idEntries.common := pid^.idEntries.common;
   pgid^.idEntries.nID := 1;
   nSize := pid^.idEntries.common.dwBytesInRes;

   GetMem(pvFile, nSize);
   SetFilePointer(hFile, pid^.idEntries.dwImageOffset, nil, FILE_BEGIN);
   ReadFile(hFile, pvFile^, nSize, uRead, nil);
   CloseHandle(hFile);

   hInst:=BeginUpdateResource(destexe, False);
   if hInst > 0 then
      begin
      UpdateResource(hInst, RT_ICON, MAKEINTRESOURCE(1), LANG_NEUTRAL, pvFile, nSize);
      EndUpdateResource(hInst, False);
      result := True;
      end;

   FreeMem(pvFile);
   FreeMem(pgid);
   FreeMem(pid);
   end;
end;

end.
使用名称
iconchanger
保存上述单元,并将其添加到项目中。复制文件后,按如下方式调用该单元

procedure TForm1.BtnChangeIconClick(Sender: TObject);
begin
    iconchanger.UpdateApplicationIcon(PChar(SourceFileName), PChar(DestinationFileName));
end;

DestinationFileName
现在将使用
SourceFileName
图标

替换复制文件的图标资源。复制exe文件是一个坏主意,原因很多。使用命令行参数指定行为,并根据这些参数选择图标。或者,使用app1.exe代替命令行参数同时包含这两个图标。使用互斥体之类的机制让app1检查另一个实例是否已在运行,然后更改为第二个图标。@davidhefferan问题是,我的文件将替换原始的Adobe PDF Reader,因此,我需要exe从Adobe获得图标,以避免把事情搞砸。。。不仅是在运行时,我还需要文件本身,以具有该图标。虽然是第一个exe,但没有理由保留此图标。使用Adobe PDF Reader图标的文件不仅侵犯了Adobe的版权,而且对软件用户来说也是恶意软件(如果不是,则伪装为合法软件)。这里的人不应该帮助你创建恶意软件。在Delphi 10.3+Windows 8上不起作用。甚至试图清除图标缓存。