[
  {
    "Id": "437116",
    "ThreadId": "211020",
    "Html": "<p>Thank you for providing the DotNetZip library. It's been wonderful so far.</p>\r\n<p>I'm having some trouble with replacing the SFX stub though. I'd like to provide the same &quot;use&quot; as the current SFX, just with a couple more options in the UI (I do some preprocessing on the files before they are extracted).&nbsp;</p>\r\n<p>I read the thread at: http://dotnetzip.codeplex.com/Thread/View.aspx?ThreadId=70602</p>\r\n<p>Specifically the post from <span id=\"ctl00_ctl00_MasterContent_Content_PostRepeater_ctl42_Timestamp\">Oct  15 2009 at 12:32 AM</span></p>\r\n<p><br>I implemented your logic, and can create the exe fine:</p>\r\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; string outputFile = &quot;sfx.exe&quot;;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; string sfxStub = &quot;Stub.exe&quot;;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; byte[] buffer = new byte[4000];<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; using (System.IO.FileStream output = new FileStream(outputFile, FileMode.Create))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; using (ZipFile zip = new ZipFile())<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; using (System.IO.FileStream input = new FileStream(sfxStub, FileMode.Open))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; zip.AddFile(&quot;test.txt&quot;);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int n = 1;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while ((n = input.Read(buffer, 0, buffer.Length)) &gt; 0)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; output.Write(buffer, 0, n);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; zip.Save(output);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>\r\n<p>&nbsp;</p>\r\n<p>But when I attempt to read it back in, inside the stub, I get a System.IO.FileNotFound exception on the using line:</p>\r\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Assembly assembly = Assembly.GetExecutingAssembly();<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; using (Ionic.Zip.ZipFile file = ZipFile.Read(assembly.Location))</p>\r\n<p>&nbsp;</p>\r\n<p>The other thing I realized, if I use this method, dependencies won't be included in the EXE will it? Should I run ILMerge after builds to merge the required assemblies into the stub exe, so that it's self contained?</p>\r\n<p>Thanks for any help.</p>",
    "PostedDate": "2010-04-29T07:49:39.377-07:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  },
  {
    "Id": "437281",
    "ThreadId": "211020",
    "Html": "<p>I don't know what I wrote in October, but just for clarity, I think you might want to structure your creation logic like this:</p>\r\n<div style=\"border:solid .1em #ccc;color:black;background-color:white;margin:.25em 0.5em 0 0.5em;padding:0.25em 1.75em 0.25em 1.25em\">\r\n<pre><span style=\"color:blue\">public</span> <span style=\"color:blue\">void</span> CreateSfx()\r\n{\r\n    <span style=\"color:blue\">string</span> outputFile = <span style=\"color:#a31515\">&quot;sfx.exe&quot;</span>;\r\n    <span style=\"color:blue\">string</span> sfxStub = <span style=\"color:#a31515\">&quot;Stub.exe&quot;</span>;\r\n\r\n    <span style=\"color:blue\">byte</span>[] buffer = <span style=\"color:blue\">new</span> <span style=\"color:blue\">byte</span>[4000];\r\n\r\n    <span style=\"color:blue\">using</span> (System.IO.FileStream output = <span style=\"color:blue\">new</span> FileStream(outputFile, FileMode.Create))\r\n    {\r\n        <span style=\"color:blue\">using</span> (System.IO.FileStream input = <span style=\"color:blue\">new</span> FileStream(sfxStub, FileMode.Open))\r\n        {\r\n            <span style=\"color:blue\">int</span> n = 1;\r\n            <span style=\"color:blue\">while</span> ((n = input.Read(buffer, 0, buffer.Length)) &gt; 0)\r\n            {\r\n                output.Write(buffer, 0, n);\r\n            }\r\n\r\n        }       \r\n        <span style=\"color:blue\">using</span> (ZipFile zip = <span style=\"color:blue\">new</span> ZipFile())\r\n        {\r\n            zip.AddFile(<span style=\"color:#a31515\">&quot;test.txt&quot;</span>);\r\n            zip.Save(output);\r\n        }\r\n    }\r\n}</pre>\r\n</div>\r\n<p>To me that is much more readable - it clearly shows writing the stub into the output stream, then saving the zip file into the same stream.</p>\r\n<p>Now, as for why you are getting a FileNotFoundException, you didn't provide the complete exception so I can't know what file it is.&nbsp;&nbsp; I suggest that you examine the assembly.Location and see if it makes sense to you. It should be the path to a regular filesystem file, specifically the SFX exe that you created.</p>\r\n<p>Regarding dependencies, yes, the SFX that you create this way will depend on the Ionic.Zip.dll . If you want a single-exe deployment, then normally you would need to use ILMERGE.&nbsp; But I think that ILMerge cannot preserve the signature of a strongly-named assembly when merging them, unless you have the key that was used for signing.&nbsp;&nbsp;Ionic.Zip.dll is strongly-named, and you don't have the key, therefore I don't think you can use ILMerge to embed Ionic.Zip.dll into your assembly.&nbsp; The workaround is to <a href=\"http://stackoverflow.com/questions/222655/embedding-assemblies-inside-another-assembly/625115#625115\">embed the Ionic.Zip.dll into the EXE as a resource</a>.</p>",
    "PostedDate": "2010-04-29T12:13:39.16-07:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  },
  {
    "Id": "437288",
    "ThreadId": "211020",
    "Html": "<p>&nbsp;</p>\r\n<p>Thanks for the quick reply. I meant to paste the entire exception, but somehow didn't. In collecting it just now though, I realized what the problem is. I was carelessly missing the Ionic.Zip assembly, so the FileIOException was it couldn't be found. Moving to a directory with the assemblies, it all works as expected.</p>\r\n<p>&nbsp;</p>\r\n<p>Now I'm on to read about embedding as a resource. Thanks for pointing me to that.</p>\r\n<p>&nbsp;</p>",
    "PostedDate": "2010-04-29T12:35:06.303-07:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  },
  {
    "Id": "437305",
    "ThreadId": "211020",
    "Html": "<p>Thanks for the help thus far. I seem to have it working, but with a small hack.</p>\r\n<p>I have embedded Ionic.Zip.dll as a resource, and set the build action to &quot;Embedded Resource&quot;.</p>\r\n<p>In ResolveEventArgs.Name, it is passing &quot;Ionic.Zip, Version=1.9.1.5, Culture=neutral, PublicKeyToken=edbe51ad942a3f5c&quot;.</p>\r\n<p>If I call Assembly.GetExecutingAssembly().GetManifestResourceNames(), I see MyStub.Resources.Ionic.Zip.dll</p>\r\n<p>I'm sure it's something simple like I embedded the resource wrong, but is there a way to translate the names? If I replace the call</p>\r\n<p>&nbsp;</p>\r\n<p>Stream s = a1.GetManifestResourceStream(args.Name);</p>\r\n<p>with</p>\r\n<p>Stream s = a1.GetManifestResourceStream(&quot;MyStub.Resources.Ionic.Zip.dll&quot;);</p>\r\n<p>&nbsp;</p>\r\n<p>everything works great. Sorry for the somewhat offtopic question.</p>\r\n<p>&nbsp;</p>",
    "PostedDate": "2010-04-29T13:24:33.233-07:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  },
  {
    "Id": "437347",
    "ThreadId": "211020",
    "Html": "<p>Yep&nbsp; - your logic that receives the assembly name (&quot;Ionic.Zip, Version=1.9....etc&quot;) needs to return an assembly.&nbsp; <br>Sounds like you already know how to do that.&nbsp;&nbsp;If the name begins with Ionic.Zip, then you know it wants the resource stream with the name MyStub.Resources.Ionic.Zip.dll. &nbsp;</p>\r\n<p>Maybe you are concerned about the name mismatch.&nbsp; But the names of embedded streams are part of a different naming scope than the assemblies. So, the fact that the resource stream is not named &quot;Ionic.Zip.dll&quot; is not a concern, as long as you know how to map between names of resource streams and names of assemblies that you need to resolve.</p>\r\n<p>&nbsp;</p>\r\n<p>&nbsp;</p>\r\n<p>&nbsp;</p>",
    "PostedDate": "2010-04-29T16:14:08.65-07:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  }
]