0

I'm trying to embed some .exe and .dll files into my application (simply by including required files into my project, right-click them and change Build Action to "Embedded Resource"). Here is my code to extract:

private void ExtractTo(string path){
   string filename = "MyNamespace.Resources.MyEmbeddedEXEfile.exe";
   Assembly asm = Assembly.GetExecutingAssembly();
   string[] resourceNames = asm.GetManifestResourceNames();
   if(resourceNames.Contains(filename)){
      Stream s = asm.GetManifestResourceStream(filename);
      byte[] buffer = new byte[s.Length];
      File.WriteAllBytes(path + "\\MyEXEfile.exe", buffer);
   }
}

It seemed to work well, the embedded file was extracted to the Path passed in, it has the same size to the file I included in my project and embedded as resource. But it seemed to be corrupted, after clicking on the extracted EXE file, an error dialog displayed saying that "The version of this file is not compatible with the version of Windows you're running. Check your computer's system information to see whether you need an x86 (32-bit) or x64 (64-bit) of the program, and then contact your software publisher." Well, I'm exactly the publisher of that software =)).

I'm using Windows 7 Ultimate 64 bit. The original file (which I chose to embed) is a 32-bit file. I have also tried with a dll file and the extracted dll file also couldn't work as the original one.

Could you please point out what's wrong in my code for extracting the resource or the file is corrupted right after I embed it as resource???

Your help would be highly appreciated. Thanks.

King King
  • 61,710
  • 16
  • 105
  • 130
  • You have made no effort to solve the problem yourself. Did you check if file is saved to disk? Did you check if saved file is identical to original file you embedded to your assembly? Did you check if original file runs in the first place? – Nikola Radosavljević Apr 06 '13 at 17:57
  • @NikolaRadosavljević he actually did, you just need to read a bit: file saved has the same size, and he did try to execute. (weird...has he doesn't actually read...but still) – Julián Urbano Apr 06 '13 at 18:00
  • @KingKing this might help too http://stackoverflow.com/questions/96732/embedding-one-dll-inside-another-as-an-embedded-resource-and-then-calling-it-fro?lq=1 – Julián Urbano Apr 06 '13 at 18:04

1 Answers1

6

This:

Stream s = asm.GetManifestResourceStream(filename);
byte[] buffer = new byte[s.Length];

...doesn't actually copy the stream into the buffer. All you've done here is allocate an empty buffer of the correct length.

You need to do something like this:

s.CopyTo(File.Create(path));

...where CopyTo was added in .NET 4.0.

Roger Lipscombe
  • 89,048
  • 55
  • 235
  • 380
  • I'm using .NET 3.5, is there any other method for that? Thanks. – King King Apr 06 '13 at 17:57
  • @KingKing `s.Read` and then write to the file – Julián Urbano Apr 06 '13 at 17:58
  • @caerolus thanks, I'm looking for a very short method, otherwise I have to write a while loop, in fact my embedded file size can exceed the maximum integer (a long), so a while loop is needed. Thanks! – King King Apr 06 '13 at 18:26
  • @KingKing your embedded file size can exceed an int? whaaaaat kind of dll is that? – Julián Urbano Apr 06 '13 at 19:14
  • No, in this question I reckoned only .exe and .dll but in fact I may want to embed a large file of another type (a database file is a good example). Thanks, I just tried testing with a .exe or .dll first because I can check the success of the extraction easily by try executing the exe file or using the .dll file in a project... – King King Apr 06 '13 at 21:14
  • A better way to check the success would be to verify a SHA1 hash of the file. This works for arbitrary files. – Roger Lipscombe Apr 07 '13 at 06:06