private void Update(Dictionary <string, string> files) { Thread thread = new Thread(new ThreadStart(() => { this.install_path.Dispatcher.BeginInvoke(new Action(() => { this.install_path.Content = installPath; })); cd = new CountDown(10); cd.OnTickEvent += (uint t) => { this.counter_label.Dispatcher.BeginInvoke(new Action(() => { this.counter_label.Content = string.Format("Installation will begin in {0}s...", t); })); }; cd.Start(); cd.OnTimerDoneEvent += () => { this.path_change_label.Dispatcher.Invoke(new Action(() => { this.path_change_label.Visibility = Visibility.Collapsed; })); this.counter_label.Dispatcher.BeginInvoke(new Action(() => { this.counter_label.Content = string.Format("Downloading files...\r\n 0/{0} completed", files.Count); })); Thread[] threads = new Thread[files.Count]; Dictionary <string, double> progress = new Dictionary <string, double>(); int index = 0; foreach (var file in files) { string fileUrl = url + file.Key; string fileSavePath = installPath + '\\' + file.Key; HttpRequestHelper req = new HttpRequestHelper(fileUrl, HttpRequestHelper.HttpReqMode.GET); req.OnRequestDoneEvent += (byte[] data) => { //this.counter_label.Dispatcher.BeginInvoke(new Action(() => //{ // this.counter_label.Content = // string.Format("Downloaded {0}.", file.Key); //})); if (System.IO.File.Exists(fileSavePath)) { System.IO.File.Delete(fileSavePath); } FileStream fs = new FileStream(fileSavePath, FileMode.CreateNew); fs.Write(data, 0, data.Length); fs.Close(); fs.Dispose(); int completedThreadCount = 1; foreach (var t in threads) { if (t.ThreadState == System.Threading.ThreadState.Stopped) { ++completedThreadCount; } //if (!t.IsAlive) //{ // t.Abort(); //} } this.counter_label.Dispatcher.BeginInvoke(new Action(() => { this.counter_label.Content = string.Format("Downloading files...\r\n {0}/{1} completed", completedThreadCount, threads.Length); if (completedThreadCount == threads.Length) { // Create Desktop Shortcut if ((bool)this.create_ink_checkbox.IsChecked) { string ShortcutName = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + "\\osu!.lnk"; if (System.IO.File.Exists(ShortcutName)) { System.IO.File.Delete(ShortcutName); } WshShell shell = new WshShell(); IWshShortcut wshShortcut = shell.CreateShortcut(ShortcutName); wshShortcut.TargetPath = this.installPath + "\\osu!.exe"; wshShortcut.Save(); } this.counter_label.Content = "Installation completed\r\nthis program will be exited in 3 sec."; Task t = Task.Factory.StartNew(() => { Task.Delay(3000).Wait(); //string programPath = this.installPath + "\\osu!.exe"; //Process p = new Process(); //p.StartInfo.FileName = programPath; //p.Start(); System.Windows.Application.Current.Dispatcher.Invoke(() => { System.Windows.Application.Current.Shutdown(); }); }); } })); }; req.OnPacketReceiveEvent += (long maxSize, long currentSize) => { try { string url = req.GetUrl(); string fileName = url.Substring(url.LastIndexOf('/')); if (progress.ContainsKey(fileName)) { progress[fileName] = currentSize * 100.0 / maxSize; } else { progress.Add(fileName, currentSize * 100.0 / maxSize); } double sum = 0.0; foreach (var f in progress) { sum += f.Value; } double avg = sum / files.Count; this.progress_bar.Dispatcher.Invoke(new Action(() => { this.progress_bar.Value = avg; })); } catch (Exception) { } }; threads[index] = new Thread(new ThreadStart(() => { try { req.DoRequest(); } catch (Exception) { this.counter_label.Dispatcher.Invoke(new Action(() => { string url = req.GetUrl(); string filename = url.Substring(url.LastIndexOf('/')); this.counter_label.Content = string.Format("Failed to download {0}", filename); })); } })); threads[index++].Start(); } }; // 更新 // TODO here })); thread.Start(); }
private void CheckUpdateGrid_Loaded(object sender, RoutedEventArgs e) { // 更新事件处理 this.AddMessage("Checking for updates...", black); // 自己写更新事件吧( // TODO: here HttpRequestHelper req = new HttpRequestHelper(url + "/Infos.json", HttpRequestHelper.HttpReqMode.GET); req.OnRequestDoneEvent += (byte[] data) => { // 在此判断是否更新 string json = Encoding.GetEncoding("utf-8").GetString(data); // C# 自带类的json解析器 JavaScriptSerializer js = new JavaScriptSerializer(); FileSystem[] files = js.Deserialize <FileSystem[]>(json); MD5 md5 = new MD5CryptoServiceProvider(); // 要下载的文件内容 Dictionary <string, string> fileMD5 = new Dictionary <string, string>(); string location = Utils.GetClientLocation(); if (!string.IsNullOrEmpty(location)) { DirectoryInfo directory = new DirectoryInfo(location); FileInfo[] fileInfos = directory.GetFiles(); this.installPath = location; this.Dispatcher.Invoke(new Action(() => { this.AddMessage(string.Format("Local installation found, computing MD5 of files..."), green); })); foreach (FileInfo fi in fileInfos) { // 过滤掉不存在于json的文件 if (!Utils.RemoteFileContains(files, fi.Name)) { continue; } if (fi.Extension == ".dll" || fi.Extension == ".exe") { FileStream fs = new FileStream(fi.FullName, FileMode.Open); byte[] b = new byte[fs.Length]; if (fs.Read(b, 0, (int)fs.Length) > 0) { byte[] hash = md5.ComputeHash(b); string shash = ""; foreach (byte bi in hash) { shash += string.Format("{0:X2}", bi); } fileMD5.Add(fi.Name, shash); } fs.Close(); fs.Dispose(); } } } else if (Directory.Exists(Environment.CurrentDirectory + "\\osu!")) { this.installPath = Environment.CurrentDirectory + "\\osu!"; } // 如果该文件夹是根目录,那就在根目录下面创建新的文件夹 // 防止文件安装在磁盘根目录 else if (Environment.CurrentDirectory == Directory.GetDirectoryRoot(Environment.CurrentDirectory) || Directory.GetFiles(Environment.CurrentDirectory).Length + Directory.GetDirectories(Environment.CurrentDirectory).Length != 1) { Directory.CreateDirectory(Environment.CurrentDirectory + "\\osu!"); this.installPath = Environment.CurrentDirectory + "\\osu!"; } else { this.installPath = Environment.CurrentDirectory; } foreach (var f in files) { if (f.type != "file") { continue; } string ext = f.Name.Substring(f.Name.LastIndexOf('.')); if (ext == ".dll" || ext == ".exe") { if (!System.IO.File.Exists(installPath + "\\" + f.Name)) { fileMD5.Add(f.Name, f.MD5); } else { FileInfo fi = new FileInfo(Path.Combine(this.installPath, f.Name)); TimeSpan ts = fi.LastWriteTimeUtc - new DateTime(1970, 1, 1).ToUniversalTime(); if (ts.TotalSeconds >= f.mtime) { continue; } FileStream _fs = new FileStream(installPath + "\\" + f.Name, FileMode.Open); byte[] hash_b = md5.ComputeHash(_fs); string hash_s = ""; foreach (var b in hash_b) { hash_s += string.Format("{0:x2}", b); } if (hash_s != f.MD5) { fileMD5.Add(f.Name, f.MD5); } } } } md5.Dispose(); this.Dispatcher.Invoke(new Action(() => { this.AddMessage( string.Format("Comparing Process completed, {0} files need to update!", fileMD5.Count), green); })); // 其他线程必须使用 Dispatcher 来更新 UI this.Dispatcher.Invoke(new Action(() => { if (fileMD5.Count != 0) { this.AddMessage("Will go to update page in 3s.", green); Thread thread = new Thread(new ThreadStart(() => { Thread.Sleep(3000); this.Dispatcher.BeginInvoke(new Action(() => { this.CheckUpdateGrid.Visibility = Visibility.Collapsed; this.UpdateGrid.Visibility = Visibility.Visible; this.Update(fileMD5); })); })); thread.Start(); } else { this.AddMessage("No updates for available. The program will exit in 3s.", red); Task t = Task.Factory.StartNew(() => { Task.Delay(3000).Wait(); System.Windows.Application.Current.Dispatcher.Invoke(() => { System.Windows.Application.Current.Shutdown(); }); }); } })); }; new Thread(new ThreadStart(() => { try { // 开始请求 req.DoRequest(); } catch (Exception ex) { // 同上 this.Dispatcher.Invoke(new Action(() => { // this.AddMessage(ex.GetType().FullName + ":", red); this.AddMessage(ex.Message, red); return; })); } })).Start(); }