Asp.Net實如今線網站安裝(上)

在不少年前,筆者在使用z-blog搭建我的部落格的時候,最大的感覺就是z-blog在線安裝功能!php

由於在那個時候,以幾K每秒的速度上傳一個幾M或者十幾M的壓縮包到虛擬主機上,是一個很痛苦的事情。特別是主機不支持在線解壓功能,只能一個一個文件上傳的時候。web

雖然z-blog實現該功能的只有php版本與之前的ASP版本,可是對於asp.net,咱們也能夠作到一樣的事情,只須要一個幾K的ASPX文件,上傳到服務器,就能夠實現自動下載網站壓縮包,解壓並安裝!算法

 

原本我擔憂bin目錄文件變動,會引起異常,可是實測結果很好。服務器

本文將經過三個步驟,實現現如下目標:asp.net

1.實現Asp.Net在線網站安裝異步

2.儘可能使用最少的文件(實際咱們只須要一個aspx頁)網站

 

步驟 一. 下載和解壓spa

下載的話,咱們能夠直接使用WebClient下載便可,新建一個aspx頁,命名叫  DownloadAndDeCompress.aspx  把對應的cs文件刪掉,並刪除頁中全部內容,在第一行中輸入如下代碼:.net

<%@ Page Language="C#" AutoEventWireup="true" Async="true"  %>

注意這行的Async="true"這句,這是表示當前頁面容許異步執行,由於咱們等下須要在下載時作進度條,因此必須加上此項。code

而後再把如下代碼拷貝到頁面中:

<script type="text/C#" runat="server"> 
protected void Page_Load(object sender, EventArgs e) { using (System.Net.WebClient wc = new System.Net.WebClient()) { wc.DownloadProgressChanged += new System.Net.DownloadProgressChangedEventHandler(downloadProgressChanged); wc.DownloadFileCompleted += new System.ComponentModel.AsyncCompletedEventHandler(downloadFileCompleted); wc.DownloadFileAsync(new Uri("http://www.jiniannet.com/setup.zip"), Server.MapPath("~/setup.zip")); } } private void downloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e) { Response.Write("<script>window.parent.DeCompress()</"+"script>"); Response.Flush(); DeCompress(Server.MapPath("~/setup.zip"), Server.MapPath("~/")); Response.Write("<script>window.parent.DeCompressCompleted()</"+"script>"); Response.Flush(); } private void downloadProgressChanged(object sender, System.Net.DownloadProgressChangedEventArgs e) { //script Response.Write("<script>window.parent.DownloadProgressChanged(" + e.ProgressPercentage.ToString() + ")</"+"script>"); Response.Flush(); } public void DeCompress(string fileName, string dirPath) { using (System.IO.Stream source = System.IO.File.OpenRead(fileName)) { using (System.IO.Stream destination = new System.IO.MemoryStream()) { using (System.IO.Compression.GZipStream input = new System.IO.Compression.GZipStream(source, System.IO.Compression.CompressionMode.Decompress, true)) { byte[] bytes = new byte[4096]; int n; while ((n = input.Read(bytes, 0, bytes.Length)) != 0) { destination.Write(bytes, 0, n); } } destination.Flush(); destination.Position = 0; DeSerializeFiles(destination, dirPath); } } } private void DeSerializeFiles(System.IO.Stream s, string dirPath) { System.Runtime.Serialization.Formatters.Binary.BinaryFormatter b = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); System.Collections.Generic.Dictionary<string, object> list = (System.Collections.Generic.Dictionary<string, object>)b.Deserialize(s); DeFiles(list, dirPath); } private void DeFiles(System.Collections.Generic.Dictionary<string, object> list, string dirPath) { foreach (System.Collections.Generic.KeyValuePair<string, object> n in list) { string newName = string.Concat(dirPath, n.Key.Remove(0, 1)); if (n.Key[0] == '0') { System.IO.Directory.CreateDirectory(newName); if (n.Value != null) { DeFiles((System.Collections.Generic.Dictionary<string, object>)n.Value, dirPath); } } else { using (System.IO.FileStream fs = new System.IO.FileStream(newName, System.IO.FileMode.Create, System.IO.FileAccess.Write)) { byte[] bytes = (byte[])n.Value; fs.Write(bytes, 0, bytes.Length); fs.Close(); } } } } </script>

 

page_load中,咱們直接經過webclient下載http://www.jiniannet.com/setup.zip這個安裝包,第二個downloadFileCompleted方法用來向父頁面輸出下載完成事件與解壓完成事件,第三個方法downloadProgressChanged則表示下載進度條。最後面的三個方法爲解壓相關方法。

這裏咱們用使用Flush來即時輸出信息,再配合一個父頁面,就能夠作進度條處理效果,因此原則上最少會有二個文件,可是最終咱們只會保留一個文件,這個在後面會講處處理方法。

壓縮算法的話,雖然如今壓縮算法有不少種,像7Z,rar等壓縮比例是至關高的,ZIP的壓縮結果也不錯,可是咱們要考慮文件精減,若是這個在線安裝包搞得比完整安裝包還大,就徹底沒意義了,並且咱們的最終追求目標是隻須要一個aspx頁面,除了這個aspx頁面,不須要再下任何文件。因此,我選擇在這裏使用系統自帶的Gzip算法,這樣能夠儘可能解少咱們的安裝文件對外面DLL的依賴,與儘可能減小安裝文件的SIZE(注:不要被下載文件後綴ZIP迷惑,此ZIP也不能直接被壓縮文件解壓,具體緣由我將會在下面講到)。

至此,最主要的一個功能性頁面已經完成,在下一篇文章,我將介紹若是製做網站安裝包與最後的install.aspx頁面製做。

(原創做品,轉載請註明做者與出處,本文同時發佈於www.jiniannet.com)

相關文章
相關標籤/搜索