注: 原本是替换图标来着, 但还没读取原本图标信息代码, 而自己又想分享出来所以变成给没有图标的exe加图标
代码来源:使用deepseek从vb替换exe文件转译出的C#代码,deepseek真是神器啊.写的代码能直接运行,我自己找不到的问题,deepseek轻轻松松分析出来并优化.复制即可使用.属实流弊👍
相关资料还有:C#更新exe文件图标 - fanu - 博客园 代码实现pe文件图标替换_pe图标修改-CSDN博客
以下是GIF演示(代码在GIF下面):
以下是运行成功的代码:
//.cs 文件类型,便于外部编辑时使用// 引用必要的命名空间using System.IO;using System.Runtime.InteropServices;using System.Windows.Forms;// Quicker将会调用的函数。可以根据需要修改返回值类型。public static void Exec(Quicker.Public.IStepContext context){//var oldValue = context.GetVarValue("varName"); // 读取动作里的变量值//MessageBox.Show(oldValue as string);//context.SetVarValue("varName", "从脚本输出的内容。"); // 向变量里输出值UpdateIcon(@"C:\Users\dell\Desktop\批处理调试\html\test\showPopup.exe",@"C:\Users\dell\Desktop\批处理调试\html\test\test.ico");}// API声明[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]private static extern IntPtr CreateFile(string lpFileName,uint dwDesiredAccess,uint dwShareMode,IntPtr lpSecurityAttributes,uint dwCreationDisposition,uint dwFlagsAndAttributes,IntPtr hTemplateFile);[DllImport("kernel32.dll", SetLastError = true)]private static extern bool ReadFile(IntPtr hFile,byte[] lpBuffer,uint nNumberOfBytesToRead,out uint lpNumberOfBytesRead,IntPtr lpOverlapped);[DllImport("kernel32.dll", SetLastError = true)]private static extern uint SetFilePointer(IntPtr hFile,int lDistanceToMove,IntPtr lpDistanceToMoveHigh,uint dwMoveMethod);[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]private static extern IntPtr BeginUpdateResource(string pFileName,[MarshalAs(UnmanagedType.Bool)]bool bDeleteExistingResources);[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]private static extern bool UpdateResource(IntPtr hUpdate,IntPtr lpType,IntPtr lpName,ushort wLanguage,byte[] lpData,uint cbData);[DllImport("kernel32.dll", SetLastError = true)]private static extern bool EndUpdateResource(IntPtr hUpdate,[MarshalAs(UnmanagedType.Bool)]bool fDiscard);[DllImport("kernel32.dll", SetLastError = true)]private static extern bool CloseHandle(IntPtr hObject);// 常量定义private const uint GENERIC_READ = 0x80000000;private const uint OPEN_EXISTING = 3;private const uint FILE_ATTRIBUTE_NORMAL = 0x80;private const uint FILE_BEGIN = 0;private static readonly IntPtr RT_ICON = (IntPtr)3;private static readonly IntPtr RT_GROUP_ICON = (IntPtr)14;private static readonly IntPtr INVALID_HANDLE_VALUE = (IntPtr)(-1);// 结构体定义[StructLayout(LayoutKind.Sequential)]private struct ICONDIR{public ushort idReserved;public ushort idType;public ushort idCount;}[StructLayout(LayoutKind.Sequential)]private struct ICONDIRENTRY{public byte bWidth;public byte bHeight;public byte bColorCount;public byte bReserved;public ushort wPlanes;public ushort wBitCount;public uint dwBytesInRes;public uint dwImageOffset;}[StructLayout(LayoutKind.Sequential, Pack = 2)]private struct GRPICONDIRENTRY{public byte bWidth;public byte bHeight;public byte bColorCount;public byte bReserved;public ushort wPlanes;public ushort wBitCount;public uint dwBytesInRes;public ushort nID;}//static void Main(string[] args)//{// if (args.Length != 2)// {// Console.WriteLine("Usage: IconUpdater.exe [TargetExe] [IconFile]");// return;// }//// UpdateIcon(args[0], args[1]);//}static void UpdateIcon(string exeFile, string iconFile){IntPtr hIconFile = INVALID_HANDLE_VALUE;IntPtr hUpdate = IntPtr.Zero;try{// 打开图标文件hIconFile = CreateFile(iconFile, GENERIC_READ, 0, IntPtr.Zero,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, IntPtr.Zero);if (hIconFile == INVALID_HANDLE_VALUE)throw new IOException("无法打开图标文件", Marshal.GetLastWin32Error());// 读取图标文件头ICONDIR iconDir = ReadStruct<ICONDIR>(hIconFile);if (iconDir.idType != 1)throw new InvalidDataException("无效的图标文件");// 读取图标条目ICONDIRENTRY[] entries = new ICONDIRENTRY[iconDir.idCount];for (int i = 0; i < iconDir.idCount; i++){entries[i] = ReadStruct<ICONDIRENTRY>(hIconFile);}// 开始更新资源hUpdate = BeginUpdateResource(exeFile, false);if (hUpdate == IntPtr.Zero)throw new IOException("无法开始更新资源", Marshal.GetLastWin32Error());// 写入图标资源for (ushort i = 0; i < iconDir.idCount; i++){byte[] iconData = ReadIconData(hIconFile, entries[i]);if (!UpdateResource(hUpdate, RT_ICON, (IntPtr)(i + 1), 0, iconData, (uint)iconData.Length))throw new IOException("更新图标资源失败", Marshal.GetLastWin32Error());}// 创建图标组资源byte[] groupData = CreateGroupIconData(iconDir, entries);if (!UpdateResource(hUpdate, RT_GROUP_ICON, (IntPtr)32512, 0, groupData, (uint)groupData.Length))throw new IOException("更新图标组失败", Marshal.GetLastWin32Error());}finally{if (hUpdate != IntPtr.Zero)EndUpdateResource(hUpdate, false);if (hIconFile != INVALID_HANDLE_VALUE)CloseHandle(hIconFile);}}private static T ReadStruct<T>(IntPtr hFile) where T : struct{int size = Marshal.SizeOf<T>();byte[] buffer = new byte[size];uint bytesRead;if (!ReadFile(hFile, buffer, (uint)size, out bytesRead, IntPtr.Zero) || bytesRead != size)throw new IOException("读取文件失败", Marshal.GetLastWin32Error());GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);try{return Marshal.PtrToStructure<T>(handle.AddrOfPinnedObject());}finally{handle.Free();}}private static byte[] ReadIconData(IntPtr hFile, ICONDIRENTRY entry){byte[] data = new byte[entry.dwBytesInRes];uint bytesRead;if (SetFilePointer(hFile, (int)entry.dwImageOffset, IntPtr.Zero, FILE_BEGIN) == 0xFFFFFFFF)throw new IOException("设置文件指针失败", Marshal.GetLastWin32Error());if (!ReadFile(hFile, data, entry.dwBytesInRes, out bytesRead, IntPtr.Zero) || bytesRead != entry.dwBytesInRes)throw new IOException("读取图标数据失败", Marshal.GetLastWin32Error());return data;}private static byte[] CreateGroupIconData(ICONDIR dir, ICONDIRENTRY[] entries){using (MemoryStream ms = new MemoryStream())using (BinaryWriter writer = new BinaryWriter(ms)){// 写入组头(固定3个字段,每个字段2字节)writer.Write(dir.idReserved); // ushortwriter.Write(dir.idType); // ushortwriter.Write(dir.idCount); // ushort// 手动写入每个 GRPICONDIRENTRY 条目,避免结构体对齐问题for (ushort i = 0; i < entries.Length; i++){ICONDIRENTRY entry = entries[i];// 按标准 GRPICONDIRENTRY 结构写入(共14字节)writer.Write(entry.bWidth); // bytewriter.Write(entry.bHeight); // bytewriter.Write(entry.bColorCount); // bytewriter.Write(entry.bReserved); // bytewriter.Write(entry.wPlanes); // ushortwriter.Write(entry.wBitCount); // ushortwriter.Write(entry.dwBytesInRes); // uintwriter.Write((ushort)(i + 1)); // nID: ushort(关键修正点)}return ms.ToArray();}}