Asp.Net实现在线网站安装(上)
在很多年前,笔者在使用z-blog搭建个人部落格的时候,最大的感受就是z-blog在线安装功能!
因为在那个时候,以几K每秒的速度上传一个几M或者十几M的压缩包到虚拟主机上,是一个很痛苦的事情。特别是主机不支持在线解压功能,只能一个一个文件上传的时候。
虽然z-blog实现该功能的只有php版本与以前的ASP版本,但是对于asp.net,我们也可以做到同样的事情,只需要一个几K的ASPX文件,上传到服务器,就可以实现自动下载网站压缩包,解压并安装!
本来我担心bin目录文件变更,会引发异常,但是实测结果很好。
本文将通过三个步骤,实现现以下目标:
1.实现Asp.Net在线网站安装
2.尽量使用最少的文件(实际我们只需要一个aspx页)
步骤 一. 下载和解压
下载的话,我们可以直接使用WebClient下载即可,新建一个aspx页,命名叫 DownloadAndDeCompress.aspx 把对应的cs文件删掉,并删除页中所有内容,在第一行中输入以下代码:
<%@ Page Language="C#" AutoEventWireup="true" Async="true" %>
注意这行的Async="true"这句,这是表示当前页面允许异步执行,因为我们等下需要在下载时做进度条,所以必须加上此项。
然后再把以下代码拷贝到页面中:
<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[];
int n;
while ((n = input.Read(bytes, , bytes.Length)) != )
{
destination.Write(bytes, , n);
}
}
destination.Flush();
destination.Position = ;
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(, ));
if (n.Key[] == '')
{
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, , 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)
最新文章
- 修改MySql 数据默认存储路径
- 常用数据库高可用和分区解决方案(2) — MongoDB篇
- (转)combogrid的代码实例
- linux服务之iptables与firewalld
- MVC中使用AuthorizeAttribute做身份验证操作
- Spring JdbcTemplate Querying examples
- Codeforces Round #322 (Div. 2) B. Luxurious Houses 水题
- iOS开发——文本高度
- JAVA向文件中追加内容(转)
- solr安装
- codeforces 10 D. LCIS LCIS O(n^2)算法
- JS获取浏览器窗口大小 获取屏幕,浏览器,网页高度宽度
- Div.2 C. Dasha and Password
- RabbitMQ学习3----运行和管理RabbitMQ
- [HNOI2001]求正整数
- 初步学习大数据——设置虚拟机固定ip地址
- Android--Task和BackStack高级
- mysql查看正在执行的sql语句
- elinks快捷方式
- Android之使用传感器获取相应数据