示例:SheelTool( 用于源码保护,为exe加壳) 小程序技术共享
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace SheelTool
{
/// <summary>
/// 调用kernel32.dll文件中的函数,实现exe文件资源修改功能
/// </summary>
class kernel32Tool
{
/// <summary>
/// 修改exe中的Icon。
/// (执行后,手动修改下exe文件名,即可看到icon修改效果。系统有图标缓存,所以不修改文件名,可能无法看到icon修改效果)
/// </summary>
/// <param name="exePath">.exe文件路径</param>
/// <param name="iconPath">.ico文件路径</param>
/// <param name="iconStartId">exe中Icon目录下(用zip压缩软件即可查看)的icon文件名如 2.ico, id为1</param>
/// <param name="iconCount">有的exe中含有1-8个ico</param>
public static unsafe void ReplaceExeIcon(string exePath, string iconPath, int iconStartId = 2, int iconCount = 8)
{
byte[] iconBytes = File.ReadAllBytes(iconPath);
ICONDIR iconDir = ToStruct<ICONDIR>(iconBytes, 0);
ICONDIRENTRY iconDirEntry = ToStruct<ICONDIRENTRY>(iconBytes, Marshal.SizeOf(typeof(ICONDIR)));
int iconBytesSize = iconDirEntry.dwBytesInRes;
IntPtr iconHandle = Marshal.AllocHGlobal(iconBytesSize);
Marshal.Copy(iconBytes, iconDirEntry.dwImageOffset, iconHandle, iconBytesSize);
IntPtr exeHandle = BeginUpdateResourceW(exePath, false);
int RT_ICON = 3; // 系统预设的ICON类型,有多种
for (int i = iconStartId; i < iconStartId + iconCount; i++)
{
bool b2 = UpdateResourceW(exeHandle, (char*)RT_ICON, (char*)i, 0, iconHandle, (uint)iconBytesSize);
}
EndUpdateResourceW(exeHandle, false);
Marshal.FreeHGlobal(iconHandle);
// icon组修改
//int DIFFERENCE = 11;
//int RT_GROUP_ICON = (RT_ICON + DIFFERENCE);
//GRPICONDIR groupIconDir = new GRPICONDIR();
//groupIconDir.idCount = iconDir.idCount;
//groupIconDir.idReserved = 0;
//groupIconDir.idType = 1;
//groupIconDir.idEntries = ToStruct<GRPICONDIRENTRY>(iconBytes, Marshal.SizeOf(typeof(ICONDIR)));
//groupIconDir.idEntries.nID = 0;
//int ICONDIR_Size = Marshal.SizeOf(typeof(GRPICONDIR));
//IntPtr iconDirHandle = Marshal.AllocHGlobal(ICONDIR_Size);
//Marshal.StructureToPtr(groupIconDir, iconDirHandle, false);
//bool b = UpdateResourceW(exeHandle, (char*)RT_GROUP_ICON, (char*)1, 0, iconDirHandle, (uint)ICONDIR_Size);
//Marshal.FreeHGlobal(iconDirHandle);
}
struct ICONDIRENTRY
{
byte bWidth;
byte bHeight;
byte bColorCount;
byte bReserved;
short wPlanes;
short wBitCount;
public int dwBytesInRes;
public int dwImageOffset;
};
struct ICONDIR
{
short idReserved;
short idType;
public short idCount;
//ICONDIRENTRY idEntries;
};
struct GRPICONDIRENTRY
{
byte bWidth;
byte bHeight;
byte bColorCount;
byte bReserved;
short wPlanes;
short wBitCount;
int dwBytesInRes;
public short nID;
};
struct GRPICONDIR
{
public short idReserved;
public short idType;
public short idCount;
public GRPICONDIRENTRY idEntries;
};
[DllImport("kernel32.dll")]
public static extern IntPtr BeginUpdateResourceW([In] [MarshalAs(UnmanagedType.LPWStr)] string pFileName, [MarshalAs(UnmanagedType.Bool)] bool bDeleteExistingResources);
[DllImport("kernel32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern unsafe bool UpdateResourceW([In] IntPtr hUpdate, [In] char* lpType, [In] char* lpName, ushort wLanguage, [In] IntPtr lpData, uint cb);
[DllImport("kernel32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EndUpdateResourceW([In] IntPtr hUpdate, [MarshalAs(UnmanagedType.Bool)] bool fDiscard);
public static T ToStruct<T>(byte[] bytes, int index) where T : struct
{
int size = Marshal.SizeOf(typeof(T));
IntPtr buffer = Marshal.AllocHGlobal(size);
try
{
Marshal.Copy(bytes, index, buffer, size);
return (T)Marshal.PtrToStructure(buffer, typeof(T));
}
finally
{
Marshal.FreeHGlobal(buffer);
}
}
}
}
备注: 设置下项目允许不安全代码