快捷搜索:

取经之旅——把WinForms开发的桌面应用移植到Si

6,数据文件的支配

之前,数据文件是经由过程ClickOnce一路和利用法度榜样支配的。ClickOnce会自动判断数据文件是否更新了,然后来确定是否下载这些数据文件。而在Silverlight中,假如把数据文件作为Content打包在XAP文件中,那么每次下载(或更新)XAP都邑下载这些数据文件。办理措施有两种:把数据文件零丁放在一个法度榜样集中,把法度榜样集设置为On-Demand下载或用Application Library Caching机制来缓存;或者,自定义一个数据文件下载和进级的机制。

我采纳了第二种要领,即自定义了数据文件的下载更新机制,下面就具体先容。

首先懂得一下参考资料《Silverlight: Downloading Zipped files with the WebClient (stand Silverlight 2 beta 1)》

http://www.galasoft.ch/mydotnet/articles/article-2008032301.html

接着,阐明一下我的思路:

在承载Silverlight利用法度榜样的Web利用法度榜样上建立一个文件夹,如“LCADB”

在Web真个LCADB目录中放置一个(或多个)数据文件的zip文件,和一个manifest.xml文件来描述LCADB包孕哪些文件,这些文件的最新更新光阴

每个zip文件都包孕了多少xml文件,我的根基数据都是保存在xml文件中的

假如是Out-Of-Browser的话,在Silverlight法度榜样启动的时刻,首先要反省是利用法度榜样本身否有更新,

更新完毕提示用户重启利用法度榜样,

无更新则调用InstallOrUpdateDB

假如不是OfB的话,要用InstallState属性来跳过利用法度榜样更新的代码,直接调用InstallOrUpdateDB

InstallOrUpdateDB,反省是否已经分配自力存储区(我分配了100M,数据文件解压后大年夜致用到30M,其他可能作为临时空间,这点后面论述)

假如未分配,显示一个“Install DB”的按钮给用户,让用户点击以运行IncreaseQuotaTo,这样做的缘故原由是安然机制限定了IncreaseQuotaTo措施必须由用户的事故所激发

分配完成,接着调用CheckDBManifest

假如已分配,直接调用CheckDBManifest

CheckDBManifest,用来反省办事器上的manifest.xml内容,和本地保存的manifest.xml进行对照以确定必要下载那些zip文件,这里是经由过程DownloadStringAsync措施直接得到manifest.xml的文本内容

假如必要下载zip文件,就调用DownloadAndExtract,

DownloadAndExtract,用来下载zip文件并解压到自力存储区中,这里是经由过程OpenReadAsync来获取文件流,

在OpenReadAsync异步措施完成后,解压zip文件的内容到自力存储区中,解压完成后,继承处置惩罚下一个必要下载的zip文件,并赓续重复。在此处,我对SharpZipLib进行扩展,可以把文件解压到自力存储区中。

全部流程便是这样,因为我没有安装Visio 2010,就不画流程图了。相关代码如下:

public partial class MainPage : UserControl

{

Application app = Application.Current;

public MainPage()

{

InitializeComponent();

//在OfB中才用代码去更新

if (app.InstallState==InstallState.Installed)

app.CheckAndDownloadUpdateCompleted += new CheckAndDownloadUpdateCompletedEventHandler(app_CheckAndDownloadUpdateCompleted);

}

void app_CheckAndDownloadUpdateCompleted(object sender, CheckAndDownloadUpdateCompletedEventArgs e)

{

if (e.UpdateAvailable)

{

MessageBox.Show("An application update has been downloaded. " +

"Restart the application to run the new version.");

}

else if (e.Error != null &&

e.Error is PlatformNotSupportedException)

{

MessageBox.Show("An application update is available, " +

"but it requires a new version of Silverlight. " +

"Visit the application home page to upgrade.");

}

else

{

MessageBox.Show("There is no update available.");

this.IsEnabled = true;

InstallOrUpdateDB();

}

}

private void InstallOrUpdateDB()

{

if (ProgramBase.ShouldIncreaseQuota)

{

button1.Visibility = System.Windows.Visibility.Visible;

}

else

{

this.CheckDBManifest();

}

}

private void UserControl_Loaded(object sender, RoutedEventArgs e)

{

// Do not load your data at design time.

// if (!System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))

// {

////Load your data here and assign the result to the CollectionViewSource.

//System.Windows.Data.CollectionViewSource myCollectionViewSource = (System.Windows.Data.CollectionViewSource)this.Resources["Resource Key for CollectionViewSource"];

//myCollectionViewSource.Source = your data

// }

if (app.InstallState == InstallState.Installed)

{

if (NetworkInterface.GetIsNetworkAvailable())

this.IsEnabled = false;

app.CheckAndDownloadUpdateAsync();

}

else

InstallOrUpdateDB();

}

private void CheckDBManifest()

{

if (!NetworkInterface.GetIsNetworkAvailable()) return;

WebClient wc = new WebClient();

wc.DownloadStringCompleted += new DownloadStringCompletedEventHandler(wc_DownloadStringCompleted);

wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(wc_DownloadProgressChanged);

label1.Content = "DB updated checking ...";

var url = ProgramBase.LCADBWebPath + "manifest.xml";

wc.DownloadStringAsync(new Uri(url));

}

void wc_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)

{

progressBar1.Value= e.ProgressPercentage;

}

ListLCADBZipFile> zipfilesWeb;

ListLCADBZipFile> zipfilesLocal;

int checkfileIndex = 0;

void wc_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)

{

label1.Content = "Finished DB updated checking.";

var lcadb_zipfiles_manifest = "lcadb_zipfiles_manifest.xml";

XDocument docWeb = XDocument.Parse(e.Result);

zipfilesWeb = (from m in docWeb.Descendants("file")

select new LCADBZipFile

{

Name = m.Attribute("name").Value,

Created = DateTime.Parse(m.Attribute("created").Value)

}).ToList();

using (var store = ProgramBase.OpenStore())

{

if (store.FileExists(lcadb_zipfiles_manifest))

{

var s = store.OpenFile(lcadb_zipfiles_manifest, FileMode.Open);

XDocument docLocal = XDocument.Load(s);

zipfilesLocal = (from m in docLocal.Descendants("file")

select new LCADBZipFile

{

Name = m.Attribute("name").Value,

Created = DateTime.Parse(m.Attribute("created").Value)

}).ToList();

s.Close();

}

else

{

zipfilesLocal = new ListLCADBZipFile>();

}

docWeb.Save(store.OpenFile(lcadb_zipfiles_manifest, FileMode.Create));

}

//反省哪些文件必要下载

foreach (var item in zipfilesWeb)

{

var localfile = zipfilesLocal.FirstOrDefault(o => o.Name == item.Name);

if (localfile == null || localfile.Createditem.Created)

{

qDownloadFiles.Enqueue(item.Name);

}

}

DownloadAndExtract();

}

private Queuestring> qDownloadFiles = new Queuestring>();

private void DownloadAndExtract()

{

if (qDownloadFiles.Count > 0)

{

var name = qDownloadFiles.Dequeue();

//下载并解压

WebClient wc2 = new WebClient();

wc2.OpenReadCompleted += new OpenReadCompletedEventHandler(wc2_OpenReadCompleted);

wc2.DownloadProgressChanged += new DownloadProgressChangedEventHandler(wc2_DownloadProgressChanged);

//显示下载进度

label1.Content = "Downloading " + name;

wc2.OpenReadAsync(new Uri(ProgramBase.LCADBWebPath + name));

}

else

{

//显示主页面

label1.Content = "Downloaded!";

}

}

void wc2_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)

{

progressBar1.Value = e.ProgressPercentage;

}

void wc2_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)

{

FastZip zip = new FastZip();

string path=IO.Path.Combine(ProgramBase.LCADBXmlPath,zipfilesWeb[checkfileIndex].Name.Split('_')[0]);

using (var store=ProgramBase.OpenStore())

{

if (!store.DirectoryExists(path)) store.CreateDirectory(path);

zip.ExtractZip(store, e.Result, path,FastZip.Overwrite.Always,null,"","",true);

}

//继承反省下载下一个

DownloadAndExtract();

}

class LCADBZipFile

{

public string Name { get; set; }

public DateTime Created { get; set; }

}

private void button1_Click(object sender, RoutedEventArgs e)

{

ProgramBase.CreateDBDirectory();

this.CheckDBManifest();

}

}

您可能还会对下面的文章感兴趣: