private void Download(IAsyncResult iar) { try { client.EndConnect(iar); } catch (SocketException) { #region load Server IPEndPoint remoteendpoint = (IPEndPoint)iar.AsyncState; time.Stop();//停止计时 try { if (LoadServer(remoteendpoint)) { client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); time.Start();//开始计时 client.BeginConnect(remoteendpoint, new AsyncCallback(Download), client); } else { SetControlText(labelInfo, labelCanNotConnect.Text);// SetState(State.Idle); } return; } catch (ObjectDisposedException) { SetControlText(labelInfo, labelUpdateCancel.Text); SetState(State.Idle); time.Stop(); return; } #endregion } catch (ObjectDisposedException) { SetControlText(labelInfo, labelUpdateCancel.Text); SetState(State.Idle); time.Stop(); return; } time.Stop();//停止计时 FileInfoCollection fc = new FileInfoCollection(); if (true)//是否只更新有修改过的文件 { try { fc.Load(Config.WorkPath); if (File.Exists("Resume.xml")) //存在续传记录 { if (MessageBox.Show(this, labelResume.Text, "Info", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.Yes) { XmlDocument xmlresume = new XmlDocument(); try { xmlresume.Load("Resume.xml"); XmlNode noderesume = xmlresume.SelectSingleNode("Resume/FileResume"); int id = Convert.ToInt32(noderesume.Attributes["ID"].Value); DateTime date = Convert.ToDateTime(noderesume.Attributes["Date"].Value); int length = Convert.ToInt32(noderesume.Attributes["Length"].Value); int offset = Convert.ToInt32(noderesume.Attributes["Offset"].Value); fc.SetFiletoResumeInfo(id, date, length, offset); } catch { } } else//清空临时文件夹 { Directory.Delete("temp", true); Directory.CreateDirectory("temp"); } } } catch { fc.Clear(); } File.Delete("Resume.xml"); } time.Start();//开启计时 byte[] xml = fc.SaveToBuffer(); MessageBuffer buf = new MessageBuffer(MessageType.RequeryFile, 0, 0, xml.Length); FileStream fs = null; buf.SetFileBytes(xml); int fileid = 0; //记录当前下载的文件ID int fileoffset = 0;//记录当前下载的文件偏移量 try { client.Send(buf.GetBytes());//发送已经存在文件列表 SetControlText(labelInfo, labelDownloadingList.Text); int filelength = 0;//记录所有文件的大小 int filelengthfinished = 0; //记录已经完成的文件的大小 byte[] btbufundecoded = new byte[0];//存放上次未处理的娄组 while (true) { byte[] bufmax = new byte[Config.MAX_LENGTH];//存放接收到的数组 int length = client.Receive(bufmax);//接收数据 time.Restart();//重启计时 //重写算法 byte[] btbuf = new byte[length + btbufundecoded.Length];//存放接收到及未处理的数组 if (btbufundecoded.Length > 0) { Buffer.BlockCopy(btbufundecoded, 0, btbuf, 0, btbufundecoded.Length);//将未完成的字节加入队列的开始 } Buffer.BlockCopy(bufmax, 0, btbuf, btbufundecoded.Length, length);//加入接收到的字节 int bufindex = 0; bool iscompleted = true; while (bufindex < btbuf.Length) //全部处理完也要跳出循环 { btbufundecoded = new byte[0];//清空 byte[] btmb = new byte[btbuf.Length - bufindex]; Buffer.BlockCopy(btbuf, bufindex, btmb, 0, btmb.Length);//将已经处理完的字节移出 MessageBuffer mb = new MessageBuffer(btmb); iscompleted = mb.Completed;//判断这个Message是否完整 if (!mb.Completed)//是否完整 { btbufundecoded = btmb; break;//跳出循环,未处理的在下次接收后一同处理 } else { bufindex += mb.FileLength + 13;//修改已经处理的位置 switch (mb.Header) { case MessageType.SendFileList: Config.LocalFiles.Load(mb.GetFileBytes()); filelength = Config.LocalFiles.Length; break; case MessageType.SendFile: { if (fileid != mb.FileID) //新文件 { fileid = mb.FileID; fileoffset = mb.FileOffSet; if (fs != null) { fs.Close();//写回到文件 } fs = new FileStream(string.Format("temp\\{0}.tmp", fileid), FileMode.OpenOrCreate); SetControlText(labelInfo, labelDownloading.Text + Config.LocalFiles[fileid].ToString()); } fs.Position = mb.FileOffSet; fs.Write(mb.GetFileBytes(), 0, mb.FileLength);//写入到流 fileoffset += mb.FileLength; filelengthfinished += mb.FileLength; SetProgressBarValue(progressBarDetail, (int)((double)fileoffset / (double)Config.LocalFiles[fileid].Length * 100)); SetProgressBarValue(progressBarTotal, (int)((double)filelengthfinished / (double)filelength * 100)); //刷新进度条 if (fileoffset == Config.LocalFiles[fileid].Length)//完成这个文件 { fs.Close();//从流写回到文件 fs = null; string filename = Config.WorkPath + Config.LocalFiles[fileid].ToString(); if (!Directory.Exists(Path.GetDirectoryName(filename)))//创建目的文件夹 { Directory.CreateDirectory(Path.GetDirectoryName(filename)); } if (File.Exists(filename))//如果文件存在则删除 { File.Delete(filename); } File.Move(string.Format("temp\\{0}.tmp", mb.FileID), filename);//移动文件到目的文件夹 File.SetLastWriteTime(filename, Config.LocalFiles[fileid].Date);//设置最后修改时间 Config.LocalFiles.Remove(fileid); } break; } case MessageType.SendFinished: if (true) { client.Send(MessageBuffer.ReceiveFinished.GetBytes()); } else// 用来申请某个文件中的一部分,可能用不到 { //MessageBuffer mbreqblock = new MessageBuffer(MessageType.RequeryBlock, "id", "offset", "length"); //client.Send(mbreqblock.GetBytes()); } if (filelength == 0) { SetControlText(labelInfo, labelNoUpdateFound.Text); } else { SetControlText(labelInfo, labelUpdateFinished.Text); } SetProgressBarValue(progressBarDetail, 100); SetProgressBarValue(progressBarTotal, 100); client.Shutdown(SocketShutdown.Both); client.Close(100); if (true) { if (File.Exists(Config.WorkPath + "\\" + Config.PreInstall) && !Config.CheckPreInstall()) { try { System.Diagnostics.Process pro = System.Diagnostics.Process.Start(Config.WorkPath + "\\" + Config.PreInstall); pro.WaitForInputIdle(); } catch { } } try { if (CurrentSolution != null) { XmlDocument clientxml = CreateClientXml(CurrentSolution); clientxml.Save(Config.WorkPath + @"\EEPNetClient.xml"); } } catch(Exception e) { SetMessageBox(e.Message); } try { String S = CurrentSolution.Language.ToString() + " " + CurrentSolution.IP + " " + CurrentSolution.ApPort.ToString(); System.Diagnostics.Process pro = System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo(Config.WorkPath + "\\" + Config.LaunchPath, S)); pro.WaitForInputIdle(); SetState(State.Idle); //Application.Exit(); } catch(Exception e) { SetMessageBox(e.Message); } } return; } } } } } catch (Exception e)//有些文件在copy时会有权限问题,还查不出 { if (client.Connected) { client.Send(MessageBuffer.ReceiveFinished.GetBytes()); } if (buttonStart.Text == labelStart.Text) { SetControlText(labelInfo, labelUpdateCancel.Text); if (fileid != 0 && fileoffset != Config.LocalFiles[fileid].Length)//当前文件未完成 { //存入文件 XmlDocument xmlresume = new XmlDocument(); XmlNode nodedoc = xmlresume.CreateElement("Resume"); xmlresume.AppendChild(nodedoc); XmlNode nodefileresume = xmlresume.CreateElement("FileResume"); XmlAttribute att = xmlresume.CreateAttribute("ID"); att.Value = fileid.ToString(); nodefileresume.Attributes.Append(att); att = xmlresume.CreateAttribute("Offset"); att.Value = fileoffset.ToString(); nodefileresume.Attributes.Append(att); att = xmlresume.CreateAttribute("Date"); att.Value = Config.LocalFiles[fileid].Date.ToString(); nodefileresume.Attributes.Append(att); att = xmlresume.CreateAttribute("Length"); att.Value = Config.LocalFiles[fileid].Length.ToString(); nodefileresume.Attributes.Append(att); nodedoc.AppendChild(nodefileresume); xmlresume.Save("Resume.xml");//记录续传文件的信息 } } else { SetControlText(labelInfo, string.Empty); SetMessageBox(e.Message); } SetState(State.Idle); } finally { if (fs != null) { fs.Close(); } //if (!this.Disposing) //{ // SetState(State.Idle); //} client.Close(); time.Stop(); } }
private void DownLoad(object uri) { IPEndPoint iep = (IPEndPoint)uri; LoaderObject loader = (LoaderObject)Activator.GetObject(typeof(LoaderObject), string.Format("http://{0}/LoaderObject.rem", uri)); int fileid = 0; //记录当前下载的文件ID int fileoffset = 0;//记录当前下载的文件偏移量 try { FileInfoCollection fc = new FileInfoCollection(); try { fc.Load(Config.WorkPath); if (File.Exists("Resume.xml")) //存在续传记录 { if (MessageBox.Show(this, labelResume.Text, "Info", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.Yes) { XmlDocument xmlresume = new XmlDocument(); try { xmlresume.Load("Resume.xml"); XmlNode noderesume = xmlresume.SelectSingleNode("Resume/FileResume"); int id = Convert.ToInt32(noderesume.Attributes["ID"].Value); DateTime date = Convert.ToDateTime(noderesume.Attributes["Date"].Value); int length = Convert.ToInt32(noderesume.Attributes["Length"].Value); int offset = Convert.ToInt32(noderesume.Attributes["Offset"].Value); fc.SetFiletoResumeInfo(id, date, length, offset); } catch { } } else//清空临时文件夹 { Directory.Delete("temp", true); Directory.CreateDirectory("temp"); File.Delete("Resume.xml"); } } } catch { fc.Clear(); } SetControlText(labelInfo, labelDownloadingList.Text); byte[] bt = loader.GetDownLoadList(fc.SaveToBuffer()); if (bt != null) { Config.LocalFiles.Load(bt); } byte[] btimage = loader.GetClientImage(ImageType.Client); if (btimage != null) { try { if (!Directory.Exists(Config.WorkPath)) { Directory.CreateDirectory(Config.WorkPath); } using (FileStream fs = new FileStream(string.Format("{0}\\EEPNetClient.jpg", Config.WorkPath), FileMode.OpenOrCreate)) { fs.Write(btimage, 0, btimage.Length); } } catch { } } btimage = loader.GetClientImage(ImageType.ClientMain); if (btimage != null) { try { if (!Directory.Exists(Config.WorkPath)) { Directory.CreateDirectory(Config.WorkPath); } using (FileStream fs = new FileStream(string.Format("{0}\\EEPNetClientMain.jpg", Config.WorkPath), FileMode.OpenOrCreate)) { fs.Write(btimage, 0, btimage.Length); } } catch { } } } catch (WebException e) { if (e.Status == WebExceptionStatus.ConnectFailure) { if (LoadServer(iep)) { Thread.Sleep(1000); DownLoad(uri); return; } else { SetControlText(labelInfo, labelCanNotConnect.Text); } } else { SetMessageBox(e.Message); } SetState(State.Idle); return; } catch (ThreadAbortException) { SetControlText(labelInfo, labelUpdateCancel.Text); return; } catch (Exception e) { SetMessageBox(e.Message); SetState(State.Idle); return; } try { File.Delete("Resume.xml"); System.Collections.IEnumerator ie = Config.LocalFiles.GetEnumerator(); int filelength = Config.LocalFiles.Length; int filelengthfinished = 0; if(filelength > 0) { while (ie.MoveNext()) { FileInfo fi = ((DictionaryEntry)ie.Current).Value as FileInfo; SetControlText(labelInfo, labelDownloading.Text + fi.ToString()); using (FileStream fs = new FileStream(string.Format("temp\\{0}.tmp", fi.ID), FileMode.OpenOrCreate)) { fileid = fi.ID; int length = fi.Length; int i = 0; if (Config.LocalFiles.FileResume != null && Config.LocalFiles.FileResume.ID == fi.ID) { i = Config.LocalFiles.FileOffSet;//续传文件从续传位置开始 } for (; i < length; i += Config.FILE_BLOCK_LENGTH) { int len = Math.Min(Config.FILE_BLOCK_LENGTH, length - i); byte[] btfile = loader.GetFile(fi.ID, i, len); fs.Position = i; fs.Write(btfile, 0, len); fileoffset = i + len; filelengthfinished += len; SetProgressBarValue(progressBarDetail, (int)((double)(i + len) / (double)fi.Length * 100)); SetProgressBarValue(progressBarTotal, (int)((double)filelengthfinished / (double)filelength * 100)); } } string filename = Config.WorkPath + fi.ToString(); if (!Directory.Exists(Path.GetDirectoryName(filename)))//创建目的文件夹 { Directory.CreateDirectory(Path.GetDirectoryName(filename)); } if (File.Exists(filename))//如果文件存在则删除 { File.Delete(filename); } File.Move(string.Format("temp\\{0}.tmp", fi.ID), filename);//移动文件到目的文件夹 File.SetLastWriteTime(filename, fi.Date);//设置最后修改时间 } SetControlText(labelInfo, labelUpdateFinished.Text); } else { SetControlText(labelInfo, labelNoUpdateFound.Text); } SetProgressBarValue(progressBarDetail, 100); SetProgressBarValue(progressBarTotal, 100); if (File.Exists(Config.WorkPath + "\\" + Config.PreInstall) && !Config.CheckPreInstall()) { try { System.Diagnostics.Process pro = System.Diagnostics.Process.Start(Config.WorkPath + "\\" + Config.PreInstall); pro.WaitForInputIdle(); } catch { } } try { if (CurrentSolution != null) { XmlDocument clientxml = CreateClientXml(CurrentSolution); clientxml.Save(Config.WorkPath + @"\EEPNetClient.xml"); } } catch { SetMessageBox("Can not Refresh client xml, check it's property not be readonly."); } try { String S = string.Format("{0} {1} {2} {3} {4} {5} {6} {7}", CurrentSolution.Language, CurrentSolution.IP, CurrentSolution.ApPort , CurrentSolution.Text, ProxySetting.Default.ProxyEnable, string.Format("{0}:{1}", ProxySetting.Default.ProxyAddress, ProxySetting.Default.ProxyPort) , ProxySetting.Default.ProxyUser, ProxySetting.Default.ProxyPassword); System.Diagnostics.Process pro = System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo(Config.WorkPath + "\\" + Config.LaunchPath, S)); pro.WaitForInputIdle(); SetState(State.Idle); //Application.Exit(); return; } catch(Exception e) { SetMessageBox(e.Message); SetState(State.Idle); } } catch (ThreadAbortException) { SetControlText(labelInfo, labelUpdateCancel.Text); SetState(State.Idle); } catch (Exception e) { SetMessageBox(e.Message); SetState(State.Idle); } finally { if (fileid != 0 && fileoffset != Config.LocalFiles[fileid].Length)//当前文件未完成 { //存入文件 XmlDocument xmlresume = new XmlDocument(); XmlNode nodedoc = xmlresume.CreateElement("Resume"); xmlresume.AppendChild(nodedoc); XmlNode nodefileresume = xmlresume.CreateElement("FileResume"); XmlAttribute att = xmlresume.CreateAttribute("ID"); att.Value = fileid.ToString(); nodefileresume.Attributes.Append(att); att = xmlresume.CreateAttribute("Offset"); att.Value = fileoffset.ToString(); nodefileresume.Attributes.Append(att); att = xmlresume.CreateAttribute("Date"); att.Value = Config.LocalFiles[fileid].Date.ToString(); nodefileresume.Attributes.Append(att); att = xmlresume.CreateAttribute("Length"); att.Value = Config.LocalFiles[fileid].Length.ToString(); nodefileresume.Attributes.Append(att); nodedoc.AppendChild(nodefileresume); xmlresume.Save("Resume.xml");//记录续传文件的信息 } //SetState(State.Idle); } }