[
  {
    "Id": "510978",
    "ThreadId": "231933",
    "Html": "\r\n<p>Hi</p>\r\n<p>I want to create and download a selfextracting zip file and for this I am using the following code in my asp.net application:</p>\r\n<div style=\"color:black; background-color:white\">\r\n<pre><span style=\"color:blue\">string</span> urlsXmlFileName = <span style=\"color:#a31515\">&quot;urlsXml.xml&quot;</span>;\r\n<span style=\"color:blue\">string</span> urlsXmlFilePath = Path.Combine(tempFolderPath, urlsXmlFileName);\r\n\r\n<span style=\"color:blue\">string</span> autoRunExeName = <span style=\"color:#a31515\">&quot;ImageReplacer.exe&quot;</span>;\r\n<span style=\"color:blue\">string</span> extracterStub = Server.MapPath(<span style=\"color:#a31515\">&quot;screensaverExeFiles/&quot;</span> &#43; autoRunExeName);\r\n\r\nResponse.Clear();\r\nResponse.AddHeader(<span style=\"color:#a31515\">&quot;Content-disposition&quot;</span>, <span style=\"color:#a31515\">&quot;attachment; filename=&quot;</span> &#43; <span style=\"color:#a31515\">&quot;CorbisScreensaverImageReplacer.exe&quot;</span>);\r\n\r\nResponse.AddHeader(<span style=\"color:#a31515\">&quot;Content-Description&quot;</span>, <span style=\"color:#a31515\">&quot;File Transfer&quot;</span>);\r\nResponse.AddHeader(<span style=\"color:#a31515\">&quot;Content-Transfer-Encoding&quot;</span>, <span style=\"color:#a31515\">&quot;binary&quot;</span>);\r\nResponse.ContentType = <span style=\"color:#a31515\">&quot;application/exe&quot;</span>;\r\n\r\n <span style=\"color:blue\">using</span> (System.IO.Stream instream = System.IO.File.Open(extracterStub, System.IO.FileMode.Open))\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     <span style=\"color:blue\">int</span> count = 1;\r\n     <span style=\"color:blue\">while</span> (count != 0)\r\n     {\r\n         count = instream.Read(buffer, 0, buffer.Length);\r\n         <span style=\"color:blue\">if</span> (count != 0)\r\n             Response.OutputStream.Write(buffer, 0, count);  \r\n     }\r\n     instream.Flush();\r\n     instream.Close();\r\n  \r\n    <span style=\"color:blue\">using</span> (ZipFile zip = <span style=\"color:blue\">new</span> ZipFile())\r\n     {\r\n    <span style=\"white-space:pre\">\t</span>XElement urls = <span style=\"color:blue\">new</span> XElement(<span style=\"color:#a31515\">&quot;urls&quot;</span>,\r\n                     <span style=\"white-space:pre\">\t</span><span style=\"color:blue\">from</span> image <span style=\"color:blue\">in</span> imageUrls\r\n                     <span style=\"white-space:pre\">\t</span><span style=\"color:blue\">select</span>\r\n                       <span style=\"white-space:pre\">\t</span><span style=\"color:blue\">new</span> XElement(<span style=\"color:#a31515\">&quot;url&quot;</span>,\r\n                        <span style=\"color:blue\">new</span> XAttribute(<span style=\"color:#a31515\">&quot;imageId&quot;</span>, image.Key), image.Value)\r\n                         );\r\n                                         \r\n   <span style=\"white-space:pre\">\t</span>XDocument xdoc = <span style=\"color:blue\">new</span> XDocument(<span style=\"color:blue\">new</span> XDeclaration(<span style=\"color:#a31515\">&quot;1.0&quot;</span>, <span style=\"color:blue\">null</span>, <span style=\"color:blue\">null</span>), urls);\r\n   <span style=\"white-space:pre\">\t</span>xdoc.Save(urlsXmlFilePath);\r\n                    \r\n    <span style=\"white-space:pre\">\t</span>ZipEntry entry = <span style=\"color:blue\">null</span>;                    \r\n    <span style=\"white-space:pre\">\t</span>entry = zip.AddFile(urlsXmlFilePath);\r\n    <span style=\"white-space:pre\">\t</span>entry.FileName = <span style=\"color:#a31515\">&quot;urlsXml.xml&quot;</span>;</pre>\r\n<pre>    <span style=\"white-space:pre\">\t</span>zip.Save(Response.OutputStream);\r\n\r\n    <span style=\"white-space:pre\">\t</span>Response.Flush();\r\n                        \r\n    <span style=\"white-space:pre\">\t</span>Directory.Delete(tempFolderPath, <span style=\"color:blue\">true</span>);\r\n   <span style=\"white-space:pre\">\t</span>HttpContext.Current.ApplicationInstance.CompleteRequest();</pre>\r\n<pre>}</pre>\r\n<pre><span style=\"font-size:13.3333px\">}</span></pre>\r\n<pre>On running the downloaded exe&nbsp;created by the above code,I am getting following error:&nbsp;</pre>\r\n<pre><strong> zipEntry:: ReadDirEntry():Bad signature(0xFE160400) at position 0x000006FC</strong></pre>\r\n</div>\r\n<p>But &nbsp;things &nbsp;work properly if I use following code:</p>\r\n<div style=\"color:black; background-color:white\">\r\n<pre><span style=\"color:blue\">string</span> urlsXmlFileName = <span style=\"color:#a31515\">&quot;urlsXml.xml&quot;</span>;\r\n<span style=\"color:blue\">string</span> urlsXmlFilePath = Path.Combine(tempFolderPath, urlsXmlFileName);\r\n\r\n<span style=\"color:blue\">string</span> autoRunExeName = <span style=\"color:#a31515\">&quot;CorbisScreensaverImagesReplacer.exe&quot;</span>;\r\n<span style=\"color:blue\">string</span> extracterStub = Server.MapPath(<span style=\"color:#a31515\">&quot;screensaverExeFiles/&quot;</span> &#43; autoRunExeName);\r\n\r\nResponse.Clear();\r\nResponse.AddHeader(<span style=\"color:#a31515\">&quot;Content-disposition&quot;</span>, <span style=\"color:#a31515\">&quot;attachment; filename=&quot;</span> &#43; <span style=\"color:#a31515\">&quot;CorbisScreensaverImageReplacer.exe&quot;</span>);\r\nResponse.AddHeader(<span style=\"color:#a31515\">&quot;Content-Description&quot;</span>, <span style=\"color:#a31515\">&quot;File Transfer&quot;</span>);\r\nResponse.AddHeader(<span style=\"color:#a31515\">&quot;Content-Transfer-Encoding&quot;</span>, <span style=\"color:#a31515\">&quot;binary&quot;</span>);\r\nResponse.ContentType = <span style=\"color:#a31515\">&quot;application/exe&quot;</span>;\r\n\r\n<span style=\"color:blue\">string</span> selfExtractingFilepath = Path.Combine(tempFolderPath, <span style=\"color:#a31515\">&quot;SetCorbisScreenSaverImages.exe&quot;</span>);\r\n<span style=\"color:blue\">using</span> (System.IO.Stream oStream = System.IO.File.Open(selfExtractingFilepath, System.IO.FileMode.OpenOrCreate))\r\n{\r\n<span style=\"color:blue\"><span style=\"white-space:pre\">\t</span><span style=\"color:#0000ff\">using</span></span> (System.IO.Stream instream = System.IO.File.Open(extracterStub, System.IO.FileMode.Open))\r\n\t{\r\n\t<span style=\"white-space:pre\">\t</span><span style=\"color:blue\">byte</span>[] buffer = <span style=\"color:blue\">new</span> <span style=\"color:blue\">byte</span>[4000];\r\n\t\t<span style=\"color:blue\">int</span> count = 1;\r\n\r\n\t\t<span style=\"color:blue\">while</span> (count != 0)\r\n\t\t{\r\n\t\t<span style=\"white-space:pre\">\t</span>count = instream.Read(buffer, 0, buffer.Length);\r\n\t\t\t<span style=\"color:blue\">if</span> (count != 0)\r\n\t\t\t{\r\n\t\t\t<span style=\"white-space:pre\">\t</span><span style=\"color:#000000\">oStream.Write(buffer, 0, count);</span>\r\n\t\t\t}\r\n\t\t}\r\n\t\t<span style=\"white-space:pre\">\t</span>instream.Flush();\r\n\t\t\tinstream.Close();\r\n\t}\r\n\t<span style=\"color:blue\">using</span> (ZipFile zip = <span style=\"color:blue\">new</span> ZipFile())\r\n\t{\r\n\t\t<pre><span style=\"white-space:pre\">\t\t</span>XElement urls = <span>new</span> XElement(<span>&quot;urls&quot;</span>,\r\n                     <span>\t</span><span>from</span> image <span>in</span> imageUrls\r\n                     <span>\t</span><span>select</span>\r\n                       <span>\t</span><span>new</span> XElement(<span>&quot;url&quot;</span>,\r\n                        <span>new</span> XAttribute(<span>&quot;imageId&quot;</span>, image.Key), image.Value)\r\n                         );</pre>\r\n<span style=\"white-space:pre\"> </span>XDocument xdoc = <span style=\"color:blue\">new</span> XDocument(<span style=\"color:blue\">new</span> XDeclaration(<span style=\"color:#a31515\">&quot;1.0&quot;</span>, <span style=\"color:blue\">null</span>, <span style=\"color:blue\">null</span>), urls);</pre>\r\n<pre> \t\txdoc.Save(urlsXmlFilePath);</pre>\r\n<pre><pre><span>\t       </span>ZipEntry entry = <span>null</span>;                    \r\n    <span>\t       </span>entry = zip.AddFile(urlsXmlFilePath);\r\n    <span>\t       </span>entry.FileName = <span>&quot;urlsXml.xml&quot;</span>;</pre>\r\n</pre>\r\n<pre>  \t\tzip.Save(oStream);</pre>\r\n<pre> \t\toStream.Flush();</pre>\r\n<pre> \t\toStream.Close();</pre>\r\n<pre>  \t\tSystem.IO.FileStream fs = <span style=\"color:blue\">null</span>;</pre>\r\n<pre>  \t\tfs = System.IO.File.Open(selfExtractingFilepath, System.IO.FileMode.Open);</pre>\r\n<pre> \t\t<span style=\"color:blue\">byte</span>[] btFile = <span style=\"color:blue\">new</span> <span style=\"color:blue\">byte</span>[fs.Length];&nbsp;</pre>\r\n<pre>\t\tfs.Read(btFile, 0, Convert.ToInt32(fs.Length));&nbsp;</pre>\r\n<pre>\t\tfs.Close();&nbsp;</pre>\r\n<pre> \t\tResponse.BinaryWrite(btFile);&nbsp;</pre>\r\n<pre>\t\tResponse.Flush();</pre>\r\n<pre>  \t\tDirectory.Delete(tempFolderPath, <span style=\"color:blue\">true</span>);&nbsp;</pre>\r\n<pre>\t\tHttpContext.Current.ApplicationInstance.CompleteRequest();</pre>\r\n<pre><span style=\"white-space:pre\">\t</span>}</pre>\r\n<pre>}</pre>\r\n</div>\r\n<p>Actually I don't want to save and read any temporary file. Could anyone explain this behavior(i.e. difference between the exes created by these two different approaches). Please give me &nbsp;some solution.</p>\r\n",
    "PostedDate": "2010-10-22T02:42:00.343-07:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  },
  {
    "Id": "511010",
    "ThreadId": "231933",
    "Html": "\r\n<p>Hi anu,</p>\r\n<p>I'm guessing a bit, but in your second example can you not replace the following:</p>\r\n<p><span style=\"color:blue\">using</span> (System.IO.Stream oStream = System.IO.File.Open(selfExtractingFilepath, System.IO.FileMode.OpenOrCreate))</p>\r\n<p>with</p>\r\n<p><span style=\"font-size:x-small; color:#0000ff\"><span style=\"font-size:x-small; color:#0000ff\"><span style=\"font-size:x-small; color:#0000ff\"></p>\r\n<p>using <span style=\"font-size:x-small\">(System.IO.</span><span style=\"font-size:x-small; color:#2b91af\"><span style=\"font-size:x-small; color:#2b91af\">Stream</span></span><span style=\"font-size:x-small\"> oStream = Response.OutputStream)</span></p>\r\nThis should write the zip file directly to the response stream and you could eliminate the need for reading back from&nbsp;the temporary disk file later in your code.</span></span></span>\r\n<p></p>\r\n<p><span style=\"font-size:x-small; color:#0000ff\"><span style=\"font-size:x-small; color:#0000ff\"><span style=\"font-size:x-small; color:#0000ff\">Hope this helps,</span></span></span></p>\r\n<p><span style=\"font-size:x-small; color:#0000ff\"><span style=\"font-size:x-small; color:#0000ff\"><span style=\"font-size:x-small; color:#0000ff\">Mike\r\n</p>\r\n<p>&nbsp;</p>\r\n</span></span></span>\r\n<p></p>\r\n",
    "PostedDate": "2010-10-22T03:44:41.017-07:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  },
  {
    "Id": "511018",
    "ThreadId": "231933",
    "Html": "\r\n<p>Actually, that might not work either. I *think* the problem is that the internal zip directory contains offsets relative to the &lt;start of the containing stream&gt;, rather than relative to the &lt;start position of the zip data&gt;.</p>\r\n<p>In&nbsp;your first&nbsp;case&nbsp;you're writing a stub header to a stream and then &quot;Save&quot;ing a zip to the same stream, so DotNetZip will include the length of the stub header in the offset calculations. In the second case you're &quot;Save&quot;in to a separate stream\r\n and then appending it to the stub header so the offsets inside the zip part are relative to the start of the zip data.</p>\r\n<p>Two ways I can think of to fix it are:</p>\r\n<p>&#43;&nbsp;Use a self-extracter stub which calculates offset calculations similar to DotNetZip (i.e.&nbsp;from the start of the stream, not the start of the zip data).</p>\r\n<p>&#43; Do what you're doing in the second example, but write to a memory stream instead so you're not creating a disk file. Not ideal, but it eliminates temporary files.</p>\r\n<p>Also, I've not tried doing this myself, so there might be some other way of doing it that makes a lot more sense.</p>\r\n<p>M</p>\r\n",
    "PostedDate": "2010-10-22T04:01:27.803-07:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  },
  {
    "Id": "511031",
    "ThreadId": "231933",
    "Html": "\r\n<p>Hi Pointy,</p>\r\n<p>Thanx for the quick reply. Sorry bt I am still not understanding ur point &nbsp;&quot;<strong>In the second case you're &quot;Save&quot;in to a separate stream and then appending it to the stub header so the offsets inside the zip part are relative to the start of the\r\n zip data.</strong>&quot;</p>\r\n<p>&nbsp;In second case I am writing stub to an outputstream first and then appending zip data to the same outputStream. the same thing is in first case except outputstream is Response.OutputStream.&nbsp;</p>\r\n",
    "PostedDate": "2010-10-22T04:26:00.347-07:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  },
  {
    "Id": "511034",
    "ThreadId": "231933",
    "Html": "\r\n<p>Hi Pointy ,&nbsp;</p>\r\n<p>One more thing that i want to mention is that in both cases I am able to extract &quot;urlsxml.xml&quot; file using winrar. &nbsp;In ExtracterStub exe I am using following code to extract my files :</p>\r\n<p></p>\r\n<pre>       using (Ionic.Zip.ZipFile zip = Ionic.Zip.ZipFile.Read(assembly.Location))\r\n               {                  \r\n                    string tempFolderPath = Path.Combine(Path.GetTempPath(),&quot;MyTemp&quot;);\r\n                    if (!Directory.Exists(tempFolderPath))\r\n                    {\r\n                        Directory.CreateDirectory(tempFolderPath);\r\n                    }\r\n                    zip.ExtractAll(tempFolderPath, Ionic.Zip.ExtractExistingFileAction.OverwriteSilently);\r\n\r\n                    if (File.Exists(Path.Combine(tempFolderPath, &quot;urlsXml.xml&quot;)))\r\n                    {\r\n                        XmlFilePath = Path.Combine(tempFolderPath, &quot;urlsXml.xml&quot;);\r\n                    }\r\n<span style=\"white-space:pre\">\t\t</span>}</pre>\r\n<p></p>\r\n<pre><br></pre>\r\n<p>&nbsp;</p>\r\n",
    "PostedDate": "2010-10-22T04:36:48.437-07:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  },
  {
    "Id": "511036",
    "ThreadId": "231933",
    "Html": "\r\n<p>Ah, I might have misread your second example. I'll need to spend a bit more time reading it over the weekend.</p>\r\n<p>I'll let you know if I find anything.</p>\r\n<p>M</p>\r\n",
    "PostedDate": "2010-10-22T04:46:42.813-07:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  },
  {
    "Id": "511132",
    "ThreadId": "231933",
    "Html": "\r\n<p>Could you double-check the second example in your original post above?</p>\r\n<p>I can't seem to see where it actually writes your xml file out to the zip. I can see a call to zip.Save(oStream), but the xml file doesn't seem to get added to the zip beforehand.</p>\r\n",
    "PostedDate": "2010-10-22T07:55:04.48-07:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  },
  {
    "Id": "511589",
    "ThreadId": "231933",
    "Html": "\r\n<p>Also, Anu12345, all the most interesting stuff in the sample code in your original post here, was contained on a single line.&nbsp; There's the creation of an XML file, saving the zip file, a bunch of IO, and some other stuff.</p>\r\n<p>Would it be possible for you to edit that post and reformat the code so that it is more easily readable?</p>\r\n<p>&nbsp;</p>\r\n",
    "PostedDate": "2010-10-23T14:49:33.6-07:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  },
  {
    "Id": "511945",
    "ThreadId": "231933",
    "Html": "\r\n<p>Hi&nbsp;</p>\r\n<p>Sorry for inconvenience. I hv edited my post. Please do let me know if there is any solution of this problem.</p>\r\n",
    "PostedDate": "2010-10-24T23:20:18.883-07:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  },
  {
    "Id": "513078",
    "ThreadId": "231933",
    "Html": "\r\n<p>Super. Much better.</p>\r\n<p>Ah, ok, I think I understand better now.</p>\r\n<p>The reason why the first version is not giving you happy results is that the offsets in your self-extracting zip are ...<em>off</em>.</p>\r\n<p>Here's the thing.&nbsp; A zip file contains a directory, somewhere in the file, which lists the position of all the zip entries in the file.&nbsp; These positions are offsets from the beginning of the file.&nbsp; An SFX is also a ZIP; it just happens to\r\n have a PE-COFF (Executable) file before all the zip content.&nbsp; This is&nbsp;no problem at all, for reading the sfx file as a regular zip file, as long the offsets are correct.&nbsp; &nbsp;Suppose you open a filesystem file (getting a FileStream), save\r\n the sfx stub into it, and then call ZipFile.Save() into that FileStream.&nbsp; ZipFile.Save() does the right thing for the zipentry offsets, by inquiring the&nbsp;Position of the FileStream before writing any data, and then adding that initial offset into\r\n any ZipEntry offsets in the zip directory.&nbsp; Does this make sense? &nbsp;</p>\r\n<p>This does not work for HttpResponse.OutputStream, because it is not possible to inquire the Position on that stream.&nbsp; Position is not defined for that stream type.&nbsp; Therefore the writes that happen within the context of ZipFile.Save() cannot do\r\n the fixup arithmetic I described just above.</p>\r\n<p>What can you do?</p>\r\n<p>One way to do it is to wrap HttpResponse.OutputStream in a wrapper stream that supports the Position property; then write the SFX stub and the ZipFile into that wrapper stream.&nbsp;Because ZipFile.Save() can inquire the Position, it will then do the right\r\n thing with the offsets.&nbsp; &nbsp;In the source for DotNetZip, there is a wrapper stream class called CountingStream that does exactly what you want;&nbsp; unfortunately it is limited to internal use. You'll have to add this code to your project to use it.</p>\r\n<p>I think it's a reasonable change request to expose CountingStream as a public class, to make what you're doing much easier.&nbsp; I';ll open a workitem for that.</p>\r\n<p>Good luck!</p>\r\n<p>&nbsp;</p>\r\n<p>&nbsp;</p>\r\n",
    "PostedDate": "2010-10-26T18:05:02.623-07:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  },
  {
    "Id": "513079",
    "ThreadId": "231933",
    "Html": "This discussion has been copied to a work item. Click <a href=\"http://dotnetzip.codeplex.com/workitem/12374\">here</a> to go to the work item and continue the discussion.",
    "PostedDate": "2010-10-26T18:07:55.093-07:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  }
]