Support Forums

Full Version: Need help
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Can anyone help me with a icon changer.
This class:
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;
        }
    }
Usage:
Code:
IconInjector.InjectIcon(filePath, iconPath);
If this works i will hug you lol...
(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.
VB.Net

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)
PM me if you need help.