12-12-2010, 04:51 PM
12-12-2010, 05:02 PM
This class:
Usage:
Code:
class IconInjector
{
[DllImport("kernel32.dll", SetLastError = true)]
//static extern bool UpdateResource(IntPtr hUpdate, string lpType, string lpName, ushort wLanguage, IntPtr lpData, uint cbData);
static extern int UpdateResource(IntPtr hUpdate, uint lpType, uint lpName, ushort wLanguage, byte[] lpData, uint cbData);
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr BeginUpdateResource(string pFileName,
[MarshalAs(UnmanagedType.Bool)]bool bDeleteExistingResources);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool EndUpdateResource(IntPtr hUpdate, bool fDiscard);
public static void InjectIcon(string execFileName, string iconFileName)
{
InjectIcon(execFileName, iconFileName, 1, 1);
}
static void InjectIcon(string execFileName, string iconFileName, uint iconGroupID, uint iconBaseID)
{
const uint RT_ICON = 3;
const uint RT_GROUP_ICON = 14;
// アイコンファイルの読み込み
IconFile iconFile = new IconFile();
iconFile.Load(iconFileName);
// リソースの更新開始
IntPtr hUpdate = BeginUpdateResource(execFileName, false);
Debug.Assert(hUpdate != IntPtr.Zero);
// RT_GROUP_ICON 書き込み
byte[] data = iconFile.CreateIconGroupData(iconBaseID);
UpdateResource(hUpdate, RT_GROUP_ICON, iconGroupID, 0, data, (uint)data.Length);
// RT_ICON書き込み
for (int i = 0; i < iconFile.GetImageCount(); i++)
{
byte[] image = iconFile.GetImageData(i);
UpdateResource(hUpdate, RT_ICON, (uint)(iconBaseID + i), 0, image, (uint)image.Length);
}
// リソースの更新終了
EndUpdateResource(hUpdate, false);
}
}
[StructLayout(LayoutKind.Sequential)]
public struct ICONDIR
{
public ushort idReserved;
public ushort idType;
public ushort idCount;
}
[StructLayout(LayoutKind.Sequential)]
public 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)]
public struct BITMAPINFOHEADER
{
public uint biSize;
public int biWidth;
public int biHeight;
public ushort biPlanes;
public ushort biBitCount;
public uint biCompression;
public uint biSizeImage;
public int biXPelsPerMeter;
public int biYPelsPerMeter;
public uint biClrUsed;
public uint biClrImportant;
}
[StructLayout(LayoutKind.Sequential, Pack = 2)]
public 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;
}
/// <summary>
/// IconFile の概要の説明です。
/// </summary>
public class IconFile
{
ICONDIR _iconDir = new ICONDIR();
ArrayList _iconEntry = new ArrayList();
ArrayList _iconImage = new ArrayList();
public IconFile()
{
}
// アイコンの持つイメージの数を取得する
public int GetImageCount()
{
return _iconDir.idCount;
}
// index番目のイメージデータを取得する
public byte[] GetImageData(int index)
{
Debug.Assert(0 <= index && index < GetImageCount());
return (byte[])_iconImage[index];
}
// アイコンファイルをロードする
public unsafe void Load(string fileName)
{
FileStream fs = null;
BinaryReader br = null;
byte[] buffer = null;
try
{
// アイコンファイルのオープン
fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
br = new BinaryReader(fs);
// ICONDIR部分の読み込み
buffer = br.ReadBytes(sizeof(ICONDIR));
fixed (ICONDIR* ptr = &_iconDir)
{
Marshal.Copy(buffer, 0, (IntPtr)ptr, sizeof(ICONDIR));
}
// ICONDIRの内容確認
Debug.Assert(_iconDir.idReserved == 0);
Debug.Assert(_iconDir.idType == 1);
Debug.Assert(_iconDir.idCount > 0);
// ICONDIRENTRYの読み込み
for (int i = 0; i < _iconDir.idCount; i++)
{
ICONDIRENTRY entry = new ICONDIRENTRY();
buffer = br.ReadBytes(sizeof(ICONDIRENTRY));
ICONDIRENTRY* ptr = &entry;
{
Marshal.Copy(buffer, 0, (IntPtr)ptr, sizeof(ICONDIRENTRY));
}
_iconEntry.Add(entry);
}
// イメージデータの読み込み
for (int i = 0; i < _iconDir.idCount; i++)
{
fs.Position = ((ICONDIRENTRY)_iconEntry[i]).dwImageOffset;
byte[] img = br.ReadBytes((int)((ICONDIRENTRY)_iconEntry[i]).dwBytesInRes);
_iconImage.Add(img);
}
byte[] b = (byte[])_iconImage[0];
}
catch (Exception ex)
{
Debug.Assert(false);
}
finally
{
if (br != null)
{
br.Close();
}
if (fs != null)
{
fs.Close();
}
}
}
// アイコングループデータのサイズ取得
unsafe int SizeOfIconGroupData()
{
return sizeof(ICONDIR) + sizeof(GRPICONDIRENTRY) * GetImageCount();
}
// アイコングループデータの作成(nBaseIDはRT_ICONの基底インデックス番号)
public unsafe byte[] CreateIconGroupData(uint nBaseID)
{
// アイコングループデータの領域確保
byte[] data = new byte[SizeOfIconGroupData()];
// アイコングループディレクトリを書き込む
fixed (ICONDIR* ptr = &_iconDir)
{
Marshal.Copy((IntPtr)ptr, data, 0, sizeof(ICONDIR));
}
int offset = sizeof(ICONDIR);
for (int i = 0; i < GetImageCount(); i++)
{
GRPICONDIRENTRY grpEntry = new GRPICONDIRENTRY();
BITMAPINFOHEADER bitmapheader = new BITMAPINFOHEADER();
// イメージデータからBITMAPINFOHEADER取得
BITMAPINFOHEADER* ptr = &bitmapheader;
{
Marshal.Copy(GetImageData(i), 0, (IntPtr)ptr, sizeof(BITMAPINFOHEADER));
}
// アイコングループエントリ作成
grpEntry.bWidth = ((ICONDIRENTRY)_iconEntry[i]).bWidth;
grpEntry.bHeight = ((ICONDIRENTRY)_iconEntry[i]).bHeight;
grpEntry.bColorCount = ((ICONDIRENTRY)_iconEntry[i]).bColorCount;
grpEntry.bReserved = ((ICONDIRENTRY)_iconEntry[i]).bReserved;
grpEntry.wPlanes = bitmapheader.biPlanes;
grpEntry.wBitCount = bitmapheader.biBitCount;
grpEntry.dwBytesInRes = ((ICONDIRENTRY)_iconEntry[i]).dwBytesInRes;
grpEntry.nID = (ushort)(nBaseID + i);
// アイコングループエントリを書き込む
GRPICONDIRENTRY* ptr2 = &grpEntry;
{
Marshal.Copy((IntPtr)ptr2, data, offset, Marshal.SizeOf(grpEntry));
}
offset += sizeof(GRPICONDIRENTRY);
}
return data;
}
}
Code:
IconInjector.InjectIcon(filePath, iconPath);
12-12-2010, 05:28 PM
If this works i will hug you lol...
12-16-2010, 02:28 PM
(12-12-2010, 05:28 PM)HakkuR Wrote: [ -> ]If this works i will hug you lol...Should do unless you're using vb.net but its easy to convert.
12-16-2010, 04:32 PM
VB.Net
Usage:
Code:
Class IconInjector
'static extern bool UpdateResource(IntPtr hUpdate, string lpType, string lpName, ushort wLanguage, IntPtr lpData, uint cbData);
<DllImport("kernel32.dll", SetLastError := True)> _
Private Shared Function UpdateResource(hUpdate As IntPtr, lpType As UInteger, lpName As UInteger, wLanguage As UShort, lpData As Byte(), cbData As UInteger) As Integer
End Function
<DllImport("kernel32.dll", SetLastError := True)> _
Private Shared Function BeginUpdateResource(pFileName As String, <MarshalAs(UnmanagedType.Bool)> bDeleteExistingResources As Boolean) As IntPtr
End Function
<DllImport("kernel32.dll", SetLastError := True)> _
Private Shared Function EndUpdateResource(hUpdate As IntPtr, fDiscard As Boolean) As Boolean
End Function
Public Shared Sub InjectIcon(execFileName As String, iconFileName As String)
InjectIcon(execFileName, iconFileName, 1, 1)
End Sub
Private Shared Sub InjectIcon(execFileName As String, iconFileName As String, iconGroupID As UInteger, iconBaseID As UInteger)
Const RT_ICON As UInteger = 3
Const RT_GROUP_ICON As UInteger = 14
' アイコンファイルの読み込み
Dim iconFile As New IconFile()
iconFile.Load(iconFileName)
' リソースの更新開始
Dim hUpdate As IntPtr = BeginUpdateResource(execFileName, False)
Debug.Assert(hUpdate <> IntPtr.Zero)
' RT_GROUP_ICON 書き込み
Dim data As Byte() = iconFile.CreateIconGroupData(iconBaseID)
UpdateResource(hUpdate, RT_GROUP_ICON, iconGroupID, 0, data, CUInt(data.Length))
' RT_ICON書き込み
For i As Integer = 0 To iconFile.GetImageCount() - 1
Dim image As Byte() = iconFile.GetImageData(i)
UpdateResource(hUpdate, RT_ICON, CUInt(iconBaseID + i), 0, image, CUInt(image.Length))
Next
' リソースの更新終了
EndUpdateResource(hUpdate, False)
End Sub
End Class
<StructLayout(LayoutKind.Sequential)> _
Public Structure ICONDIR
Public idReserved As UShort
Public idType As UShort
Public idCount As UShort
End Structure
<StructLayout(LayoutKind.Sequential)> _
Public Structure ICONDIRENTRY
Public bWidth As Byte
Public bHeight As Byte
Public bColorCount As Byte
Public bReserved As Byte
Public wPlanes As UShort
Public wBitCount As UShort
Public dwBytesInRes As UInteger
Public dwImageOffset As UInteger
End Structure
<StructLayout(LayoutKind.Sequential)> _
Public Structure BITMAPINFOHEADER
Public biSize As UInteger
Public biWidth As Integer
Public biHeight As Integer
Public biPlanes As UShort
Public biBitCount As UShort
Public biCompression As UInteger
Public biSizeImage As UInteger
Public biXPelsPerMeter As Integer
Public biYPelsPerMeter As Integer
Public biClrUsed As UInteger
Public biClrImportant As UInteger
End Structure
<StructLayout(LayoutKind.Sequential, Pack := 2)> _
Public Structure GRPICONDIRENTRY
Public bWidth As Byte
Public bHeight As Byte
Public bColorCount As Byte
Public bReserved As Byte
Public wPlanes As UShort
Public wBitCount As UShort
Public dwBytesInRes As UInteger
Public nID As UShort
End Structure
''' <summary>
''' IconFile の概要の説明です。
''' </summary>
Public Class IconFile
Private _iconDir As New ICONDIR()
Private _iconEntry As New ArrayList()
Private _iconImage As New ArrayList()
Public Sub New()
End Sub
' アイコンの持つイメージの数を取得する
Public Function GetImageCount() As Integer
Return _iconDir.idCount
End Function
' index番目のイメージデータを取得する
Public Function GetImageData(index As Integer) As Byte()
Debug.Assert(0 <= index AndAlso index < GetImageCount())
Return DirectCast(_iconImage(index), Byte())
End Function
' アイコンファイルをロードする
Public Sub Load(fileName As String)
Dim fs As FileStream = Nothing
Dim br As BinaryReader = Nothing
Dim buffer As Byte() = Nothing
Try
' アイコンファイルのオープン
fs = New FileStream(fileName, FileMode.Open, FileAccess.Read)
br = New BinaryReader(fs)
' ICONDIR部分の読み込み
buffer = br.ReadBytes(sizeof(ICONDIR))
Marshal.Copy(buffer, 0, DirectCast(ptr, IntPtr), sizeof(ICONDIR))
' ICONDIRの内容確認
Debug.Assert(_iconDir.idReserved = 0)
Debug.Assert(_iconDir.idType = 1)
Debug.Assert(_iconDir.idCount > 0)
' ICONDIRENTRYの読み込み
For i As Integer = 0 To _iconDir.idCount - 1
Dim entry As New ICONDIRENTRY()
buffer = br.ReadBytes(sizeof(ICONDIRENTRY))
Dim ptr As New Pointer(Of ICONDIRENTRY)(entry)
If True Then
Marshal.Copy(buffer, 0, DirectCast(ptr, IntPtr), sizeof(ICONDIRENTRY))
End If
_iconEntry.Add(entry)
Next
' イメージデータの読み込み
For i As Integer = 0 To _iconDir.idCount - 1
fs.Position = CType(_iconEntry(i), ICONDIRENTRY).dwImageOffset
Dim img As Byte() = br.ReadBytes(CInt(CType(_iconEntry(i), ICONDIRENTRY).dwBytesInRes))
_iconImage.Add(img)
Next
Dim b As Byte() = DirectCast(_iconImage(0), Byte())
Catch ex As Exception
Debug.Assert(False)
Finally
If br IsNot Nothing Then
br.Close()
End If
If fs IsNot Nothing Then
fs.Close()
End If
End Try
End Sub
' アイコングループデータのサイズ取得
Private Function SizeOfIconGroupData() As Integer
Return sizeof(ICONDIR) + sizeof(GRPICONDIRENTRY) * GetImageCount()
End Function
' アイコングループデータの作成(nBaseIDはRT_ICONの基底インデックス番号)
Public Function CreateIconGroupData(nBaseID As UInteger) As Byte()
' アイコングループデータの領域確保
Dim data As Byte() = New Byte(SizeOfIconGroupData() - 1) {}
' アイコングループディレクトリを書き込む
Marshal.Copy(DirectCast(ptr, IntPtr), data, 0, sizeof(ICONDIR))
Dim offset As Integer = sizeof(ICONDIR)
For i As Integer = 0 To GetImageCount() - 1
Dim grpEntry As New GRPICONDIRENTRY()
Dim bitmapheader As New BITMAPINFOHEADER()
' イメージデータからBITMAPINFOHEADER取得
Dim ptr As New Pointer(Of BITMAPINFOHEADER)(bitmapheader)
If True Then
Marshal.Copy(GetImageData(i), 0, DirectCast(ptr, IntPtr), sizeof(BITMAPINFOHEADER))
End If
' アイコングループエントリ作成
grpEntry.bWidth = CType(_iconEntry(i), ICONDIRENTRY).bWidth
grpEntry.bHeight = CType(_iconEntry(i), ICONDIRENTRY).bHeight
grpEntry.bColorCount = CType(_iconEntry(i), ICONDIRENTRY).bColorCount
grpEntry.bReserved = CType(_iconEntry(i), ICONDIRENTRY).bReserved
grpEntry.wPlanes = bitmapheader.biPlanes
grpEntry.wBitCount = bitmapheader.biBitCount
grpEntry.dwBytesInRes = CType(_iconEntry(i), ICONDIRENTRY).dwBytesInRes
grpEntry.nID = CUShort(nBaseID + i)
' アイコングループエントリを書き込む
Dim ptr2 As New Pointer(Of GRPICONDIRENTRY)(grpEntry)
If True Then
Marshal.Copy(DirectCast(ptr2, IntPtr), data, offset, Marshal.SizeOf(grpEntry))
End If
offset += sizeof(GRPICONDIRENTRY)
Next
Return data
End Function
End Class
Usage:
Code:
IconInjector.InjectIcon(filePath, iconPath)
12-19-2010, 08:45 PM
PM me if you need help.