samedi 22 décembre 2012

Best way to write ressources data in C#

using System.Globalization;
using System.Runtime.InteropServices;
using System;
class ResManager
{
    #region WINAPI
    [DllImport("kernel32.dll", SetLastError = true)]
    static extern IntPtr BeginUpdateResource(string pFileName,
        [MarshalAs(UnmanagedType.Bool)]bool bDeleteExistingResources);

    [DllImport("kernel32.dll", SetLastError = true)]
    static extern bool UpdateResource(IntPtr hUpdate, string lpType, string lpName, ushort wLanguage,
        IntPtr lpData, uint cbData);

    [DllImport("kernel32.dll", SetLastError = true)]
    static extern bool EndUpdateResource(IntPtr hUpdate, bool fDiscard);
    #endregion

    public enum ICResult
    {
        Success,
        FailBegin,
        FailUpdate,
        FailEnd
    }

    public static ICResult Write(string exeFilePath, byte[] Data, string NameRes, string TypeRes)
    {
        // Load executable
        IntPtr handleExe = BeginUpdateResource(exeFilePath, false);

        if (handleExe == null)
            return ICResult.FailBegin;

        // Get language identifier
        CultureInfo currentCulture = CultureInfo.CurrentCulture;
        int pid = ((ushort)currentCulture.LCID) & 0x3ff;
        int sid = ((ushort)currentCulture.LCID) >> 10;
        ushort languageID = (ushort)((((ushort)pid) << 10) | ((ushort)sid));

        // Get pointer to data
        GCHandle iconHandle = GCHandle.Alloc(Data, GCHandleType.Pinned);

        // Replace Data
        if (UpdateResource(handleExe, NameRes, TypeRes, languageID, iconHandle.AddrOfPinnedObject(), (uint)Data.Length))
        {
            if (EndUpdateResource(handleExe, false))
                return ICResult.Success;
            else
                return ICResult.FailEnd;
        }
        else
            return ICResult.FailUpdate;
    }
}

Aucun commentaire:

Enregistrer un commentaire