使用SilverLight构建应用程序(二)
上文说到把服务器代码加载到了本地,下面的代码就获取保存在本地的配置文件:
//获取本地的升级文件
IEnumerable<PluginConf> pluginConfsClient=null;
using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication())
{
if (store.FileExists(PublicUnit.PluginConfigFile))
{
IsolatedStorageFileStream fs = store.OpenFile(PublicUnit.PluginConfigFile, FileMode.Open, FileAccess.Read);
XElement xmlClient = XElement.Load(System.Xml.XmlReader.Create(fs));
pluginConfsClient = from c in xmlClient.DescendantsAndSelf("assembly")
select new PluginConf
{
description = c.Elements("description").SingleOrDefault().Value,
filename = c.Elements("filename").SingleOrDefault().Value,
titlename = c.Elements("titlename").SingleOrDefault().Value,
typename = c.Elements("typename").SingleOrDefault().Value,
version = c.Elements("version").SingleOrDefault().Value
};
fs.Close();
}
}
首先判断本地文件是否存在,if (store.FileExists(PublicUnit.PluginConfigFile)),如果存在就使用Linq读取;
读取完成之后,就比较本地的配置文件和服务器的配置文件,如果本地的配置和服务器的配置的版本不一致或者不存在,就表示需要从服务器重新下载:
//比较是否需要下载服务器端的插件进行升级
foreach (PluginConf pServer in pluginConfsServer)
{
bool bUpdate = true;
//判断是否需要升级,
//由于我对DLinq不熟悉,暂时使用这个方法匹配
if (pluginConfsClient != null)
{
foreach (PluginConf pClient in pluginConfsClient)
{
if (pServer.filename == pClient.filename)
{
if (pServer.version == pClient.version)
{
//如果文件名字相同和版本相同,就不需要要升级
bUpdate = false;
ShowLoadPlugin(pServer);
}
}
}
}
//判断是否需要升级
if (bUpdate)
{
this.canvasProgress.Visibility = Visibility.Visible;
progressTitle.Text = "正在下载“" + pServer.titlename + "”:";
DownLoadPlugin(pServer.filename);
}
}
//所有的下载完成之后,更新本地的记录文件
using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication())
{
if(store.FileExists(WindCloud.Main.PublicUnit.PluginConfigFile))
{
store.DeleteFile(WindCloud.Main.PublicUnit.PluginConfigFile);
}
IsolatedStorageFileStream fileStream = store.CreateFile(WindCloud.Main.PublicUnit.PluginConfigFile);
using (StreamWriter sw = new StreamWriter(fileStream))
{
Stream s = e.Result as Stream;
s.Position = 0;
Byte[] info = new Byte[s.Length];
s.Read(info, 0, (int)s.Length);
sw.BaseStream.Write(info, 0, info.Length);
sw.Flush();
sw.Close();
}
fileStream.Close();
}
下载插件文件:
void DownLoadPlugin(string pluginName)
{
WebClient wc = new WebClient();
if (wc.IsBusy)
{
wc.CancelAsync();
}
wc.OpenReadCompleted += new OpenReadCompletedEventHandler(wc_OpenReadCompleted);
wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(wc_DownloadProgressChanged);
wc.OpenReadAsync(new Uri(pluginName, UriKind.Relative));
}
下载完成之后就开始加载到显示界面:
void ShowLoadPlugin(PluginConf plugin)
{
//在界面上加载的插件内容
using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication())
{
if (store.FileExists(plugin.filename))
{
BinaryReader reader = new BinaryReader(store.OpenFile(plugin.filename, FileMode.Open, FileAccess.Read));
Byte[] info = reader.ReadBytes((int)reader.BaseStream.Length);
AssemblyPart ap = new AssemblyPart();
Assembly assembly = ap.Load(reader.BaseStream);
IPlugin element = assembly.CreateInstance(plugin.typename) as IPlugin;
//校验加载的dll是否实现了契约,当然此处也可以用Attribute来实现
element.Application =this;
element.SetVisibility(Visibility.Collapsed);
AddService(element.ToString(), element);
UserControl pageWindow = element.LoadUserControl();
//添加到界面中
pageWindow.SetValue(Grid.RowProperty, 2);
pageWindow.SetValue(Grid.ColumnProperty, 0);
this.LayoutRoot.Children.Insert(0, pageWindow);
}
}
}
至此,插件加载完成;