I am using the methods below to embed any number of files inside an executable
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.
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.