Click here to Skip to main content
15,867,835 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I am using the methods below to embed any number of files inside an executable

C#
    private void EmbedFiles(IEnumerable<string> files)
    {
        const string exePath = @"C:\SimpleApp.exe";

        foreach (var file in files)
            ResourceUpdate.WriteFileToResource(exePath, file);
    }

[DllImport("kernel32.dll", EntryPoint = "BeginUpdateResourceW", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
    internal static extern IntPtr BeginUpdateResource(string pFileName, bool bDeleteExistingResources);
    [DllImport("kernel32.dll", EntryPoint = "UpdateResourceW", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
    internal static extern bool UpdateResource(IntPtr hUpdate, string lpType, string lpName, short wLanguage, byte[] lpData, int cbData);
    [DllImport("kernel32.dll", EntryPoint = "EndUpdateResourceW", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
    internal static extern bool EndUpdateResource(IntPtr hUpdate, bool fDiscard);
    internal static void WriteFileToResource(string path, string file)
    {
       // var resourceName = Path.GetFileNameWithoutExtension(file);
        var resourceName = Path.GetFileName(file);
        using (var binaryStream = new FileStream(file, FileMode.Open, FileAccess.Read))
        {
            byte[] data = null;
            var resourceLanguage = MakeLanguageID();
            try
            {
                data = new byte[binaryStream.Length];
                binaryStream.Read(data, 0, (int)binaryStream.Length);
            }
            catch (Exception ex)
            {
                throw new Exception(string.Format("Error reading {0}: {1}", file, ex.Message), ex);
            }

            var h = BeginUpdateResource(path, false);
            Write(h, "File", resourceName, resourceLanguage, data);
        }
    }
    internal static void Write(
        IntPtr h,
        string resourceType,
        string resourceName,
        short resourceLanguage,
        byte[] buffer)
    {
        try
        {
            if (UpdateResource(h, resourceType, resourceName, resourceLanguage, buffer, buffer.Length))
                EndUpdateResource(h, false);
            else
                throw new Win32Exception(Marshal.GetLastWin32Error());
        }
        catch (Exception ex)
        {
            throw new Exception(string.Format("Error writing {0}: {1}", resourceName, ex.Message), ex);
        }
    }

    static short MakeLanguageID()
    {
        return (short)CultureInfo.CurrentUICulture.LCID;
    }


In the code below what I am trying to do is to extract the embedded files from the target exe in order to save them in a selected directory but I am not able to find the embedded resources knowing that they are there and I can see them using a tool like Resource Hacker.

C#
    var assembly = Assembly.GetExecutingAssembly();

    var names = Assembly.GetExecutingAssembly().GetManifestResourceNames();

    foreach (string filename in names)
    {
        MessageBox.Show(filename);
        //var stream = assembly.GetManifestResourceStream(filename);
        //var rawFile = new byte[stream.Length];

        //stream.Read(rawFile, 0, (int)stream.Length);

        //using (var fs = new FileStream(filename, FileMode.Create))
        //{
        //    fs.Write(rawFile, 0, (int)stream.Length);
        //}
    }
}


I created a sample project to show the problem. Please find it here

Any advice or help would be much appreciated.
Posted
Comments
Maciej Los 30-Mar-13 8:33am    
What error?
Fadi F 30-Mar-13 8:52am    
GetManifestResourceNames() cannot find the embedded resources
Sergey Alexandrovich Kryukov 1-Apr-13 14:32pm    
It means that it does not have those resources...
—SA
Fadi F 1-Apr-13 15:02pm    
But I can see my resources using Resource hacker or other tools and the size of the executable exceeds by the total size of the embedded files.
Sergey Alexandrovich Kryukov 1-Apr-13 15:13pm    
This method only shows .NET resources; each name corresponds to on *.resx; the generated resource name is derived from such file name...
Try to create such resources; and you will see.
Also, are you sure that the resources are in executing assembly? They can be in entry assembly, some other assembly of the process...
—SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900