2016-04-13 19 views
2

私はsfx(Self Extraction Archive)を返すべきRESTエンドポイントを作成しています。私はIonic.Zipを使って実際のアーカイブを作成するまで重労働をしていますが、完成したsfxアーカイブをクライアントに書き戻す方法を理解する上で問題があります。DotNetZipはResponse.OutputStreamに直接自己抽出機能を保存します

ZipFile.Save(Response.OutputStream)は、zipファイルを書き戻すためにうまくいきます。私はZipFile.SaveSelfExtractor(Response.OutputStream, options)のようなものを使用して同じことをすることができないことに驚いていました。 docsによれば、ストリームを取り込むSaveSelfExtractorのオーバーロードはありません。私はウェブ上で掘ることができるよ

例は、私がcreate my own stubとそのバック最初のストリームに書き込み、その後、同じストリームの上にzipアーカイブを作成することができる方法のいずれか

  1. 説明しています。
  2. どのようにすればtemporarily store the sfx on the serverとし、FileStreamを使用してクライアントに書き戻します。

しかし、私はsfx実行可能ファイルをサーバに一時的に保存する必要はなく、また自分自身のsfxスタブを作成したくありません。私は、すでにIonicパッケージで提供されているスタブを使用することは非常にうれしいです。

Ionic.Zip.ZipFileにsfxを作成し、それをResponse.OutputStreamに一度に書き込む方法はありますか?

これは私が今持っているものです。

using System.IO; 
using Ionic.Zip; 
using System.Web.Http; 
using Context = System.Web.HttpContext; 

namespace MyCompany.web.Controllers 
{ 
    [HttpGet] 
    public void Export() 
    { 
     var response = Context.Current.Response; 
     var stream = response.OutputStream; 

     // Create the zip archive in memory 
     using (var archive = new ZipFile()) 
     { 
      archive.Comment = "Self extracting export"; 
      archive.CompressionLevel = Ionic.Zlib.CompressionLevel.BestCompression; 

      using (var memoryStream = new MemoryStream()) 
      using (var streamWriter = new StreamWriter(memoryStream)) 
      { 
       streamWriter.WriteLine("Hello World"); 
       archive.AddEntry("testfile.txt", memoryStream.ToArray()); 
      } 

      // What I want is to write this to outputstream 
      archive.SaveSelfExtractor(/*stream*/ "export.exe", new SelfExtractorSaveOptions 
      { 
       Flavor = SelfExtractorFlavor.ConsoleApplication, 
       Quiet = true, 
       ExtractExistingFile = ExtractExistingFileAction.OverwriteSilently, 
       RemoveUnpackedFilesAfterExecute = false 
      }); 
      /*archive.Save(stream); // This will write to outputstream */ 
     } 

     response.AddHeader("Content-Disposition", "attachment; filename=export.exe"); 
     response.AddHeader("Content-Description", "File Transfer"); 
     response.AddHeader("Content-Transfer-Encoding", "binary"); 
     response.ContentType = "application/exe"; 

     response.Flush(); 
     response.Close(); 
     response.End(); 
    } 
} 
+0

[ソースコード](https://dotnetzip.codeplex.com/SourceControl/latest#Zip/ZipFile.SaveSelfExtractor.csは)ありません、指定されたストリームに直接書き込むことは何か、彼らではないことを示していると思われます自己解凍型のzipファイルを考慮に入れました。コードを修正するか、独自のコードを書く必要があります。 –

+0

パッケージから使用しているsfxスタブを抽出し、 'ZipFile.Save()'などの前にストリームに書き込むことはできませんか?私はC#でソースコードを調べて完全に理解している経験はありませんが、スタブはどこかに存在していなければなりませんか? –

+1

詳細な検査では、スタブを挿入するだけではなく、実際には正しいスタブを生成するためにオンザフライでコードをコンパイルしているようです。おそらくそれには正当な理由があり、それはおそらくストリームを直接サポートしていない理由でもあります。しかし、おそらくあなたのために一度スタブを生成し、それをジップストリームに追加する方が良いでしょう。 –

答えて

0

私は後世のためにこれを掲示しています。それは私が考え出すことができる最高の解決策でした。他の人たちはより良い解決策を提供することを歓迎します。

[HttpGet] 
    public void Export() 
    { 
     var response = Context.Current.Response; 
     var writeStream = response.OutputStream; 

     var name  = "export.exe"; 

     // Create the zip archive in memory 
     using (var archive = new Ionic.Zip.ZipFile()) 
     { 
      archive.Comment = "Self extracting export"; 
      archive.CompressionLevel = Ionic.Zlib.CompressionLevel.BestCompression; 

      using (var memoryStream = new MemoryStream()) 
      using (var streamWriter = new StreamWriter(memoryStream)) 
      { 
       streamWriter.WriteLine("Hello World"); 
       streamWriter.Flush(); 
       archive.AddEntry("testfile.txt", memoryStream.ToArray()); 
      } 

      // Write sfx file to temp folder on server 
      archive.SaveSelfExtractor(name, new Ionic.Zip.SelfExtractorSaveOptions 
      { 
       Flavor = Ionic.Zip.SelfExtractorFlavor.ConsoleApplication, 
       Quiet = true, 
       DefaultExtractDirectory = "\\temp", 
       SfxExeWindowTitle = "Export", 
       ExtractExistingFile = Ionic.Zip.ExtractExistingFileAction.OverwriteSilently, 
       RemoveUnpackedFilesAfterExecute = false 
      }); 

      // Read file back and output to response 
      using (var fileStream = new FileStream(name, FileMode.Open)) 
      { 
       byte[] buffer = new byte[4000]; 
       int n = 1; 
       while (n != 0) 
       { 
        n = fileStream.Read(buffer, 0, buffer.Length); 
        if (n != 0) 
         writeStream.Write(buffer, 0, n); 
       } 
      } 

      // Delete the temporary file 
      if (File.Exists(name)) 
      { 
       try { File.Delete(name); } 
       catch (System.IO.IOException exc1) 
       { 
        Debug.WriteLine("Warning: Could not delete file: {0} {1}", name, exc1); 
       } 
      } 
     } 

     response.AddHeader("Content-Disposition", "attachment; filename=" + name); 
     response.AddHeader("Content-Description", "File Transfer"); 
     response.AddHeader("Content-Transfer-Encoding", "binary"); 
     response.ContentType = "application/exe"; 

     response.Flush(); 
     response.Close(); 
     response.End(); 
    } 
-1
using (ZipFile zip = new ZipFile()) 
{ 
    //string DirPath = Application.StartupPath + @"\CSVfile\files" + DateTime.Now.ToString("yyMMdd"); 
    string DirPath = Server.MapPath("DoneCSV//" + ViewState["Filepath"]); 
    string savepath = DirPath + "/" + ViewState["Filepath"] + "_" + DateTime.Now.ToString("yyMMdd") + ".zip"; 
    zip.AddDirectory(DirPath); 
    zip.Save(savepath); 
    //sendmail(savepath); 
} 
+0

これは自己解凍形式のアーカイブを作成しません。 –

関連する問題