public void StartDownload(string url, string path_to_save, string file_name, string md5, bool enable_break_point = true) { if (t_download != null) { try { t_download.Abort(); } catch (Exception e) { Debug.LogWarning(e.Message); } } t_download = new Thread(new ParameterizedThreadStart(ThreadFunc)); IsThreadRunning = true; DownloadParam _param = new DownloadParam { url = url, path_to_save = path_to_save, file_name = file_name, enable_break_point = enable_break_point, md5 = md5 }; try_times = 0; _Status = Status.Checking; t_download.Start(_param); }
private void TimerCallback(object sender, System.Timers.ElapsedEventArgs args) { RemoteConfigSectionCollection lstParams = new RemoteConfigSectionCollection(config.ApplicationName); //configLocker.AcquireReaderLock(-1); //using (configLocker.AcquireReaderLock()) lock (configLocker) { foreach (ConfigEntry entry in configEntries.Values) { if (entry.IsSet) { lstParams.AddSection(entry.Name, entry.MajorVersion, entry.MinorVersion); } } //configLocker.ReleaseReaderLock(); } if (lstParams.Count == 0) { return; } //发送本地版本信息到服务器获取更新信息 lstParams = GetServerVersions(lstParams); if (lstParams.Count == 0) { return; } //如果有更新则下载新的配置文件 foreach (RemoteConfigSectionParam param in lstParams.Sections) { ThreadPool.QueueUserWorkItem( delegate(object obj) { DownloadParam dp = (DownloadParam)obj; Download(dp.Name, dp.Url, dp.LocalPath, dp.Checker); }, new DownloadParam(param.SectionName, param.DownloadUrl, GetPath(param.SectionName), CheckDownloadStream) ); } }
private void ThreadFunc(object _param_call) { CurrentSize = 0; TotalSize = 0; DownloadParam _param = _param_call as DownloadParam; if (_param == null) { IsThreadRunning = false; _Status = Status.Error; return; } Debug.LogWarning("start to download " + _param.url); if (_param.IsRedirect) { //重定向的话 不处理 失败 重试次数 _param.IsRedirect = false; } else { //重新下载 或者 分批下载 都会重试计次 ++try_times; } if (try_times > 10) { //fatal error or net error _Status = Status.Error; return; } try { _Status = Status.Verifying; if (File.Exists(_param.path_to_save + "/" + _param.file_name)) { //文件存在的话 检查一下 是否成功 不成功的话 才开始下载 _Status = Status.Verifying; if (string.IsNullOrEmpty(_param.md5) == false && _param.md5 == MD5Code.GetMD5HashFromFile(_param.path_to_save + "/" + _param.file_name)) { //ok _Status = Status.OK; this.DownloadOK(); return; } else { //md5 verify error 需要处理下载 (or断点下载) 下载完成后 才 再次校验 } } } catch (Exception e) { } _Status = Status.Checking; if (_param.enable_break_point == false) { //无需断点下载 尝试暴力删除文件 try { Directory.Delete(_param.path_to_save, true); } catch (Exception e) { Debug.LogWarning(e.Message); } } if (Directory.Exists(_param.path_to_save) == false) { try { Directory.CreateDirectory(_param.path_to_save); } catch (Exception e) { Debug.LogWarning(e.Message); } } //先打开文件 Stream file = null; using (file = (File.Exists(_param.path_to_save + "/" + _param.file_name)) ? File.OpenWrite(_param.path_to_save + "/" + _param.file_name) : file = File.Create(_param.path_to_save + "/" + _param.file_name)) { /* try * { * if (File.Exists(_param.path_to_save + "/" + _param.file_name)) * { * file = File.OpenWrite(_param.path_to_save + "/" + _param.file_name); * } * else * { * file = File.Create(_param.path_to_save + "/" + _param.file_name); * } * } * catch (Exception e) * { * Debug.LogWarning(e.Message); * }*/ try { long current_size = file.Length; if (current_size > 0) { file.Seek(current_size, SeekOrigin.Begin); } HttpWebRequest request = null; //如果是发送HTTPS请求 if (_param.url.StartsWith("https", StringComparison.OrdinalIgnoreCase)) { ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult); request = (HttpWebRequest)WebRequest.Create(_param.url); } else { request = (HttpWebRequest)WebRequest.Create(_param.url); } request.ProtocolVersion = new System.Version(1, 1); if (current_size > 0) { request.AddRange((int)current_size); CurrentSize = (int)current_size; } HttpWebResponse response = null; request.Timeout = 10000; request.ReadWriteTimeout = 10000; request.Method = "GET"; request.KeepAlive = false; response = (HttpWebResponse)request.GetResponse(); var HttpRetCode = response.StatusCode; Debug.Log("InstallDownloader http " + HttpRetCode); if (HttpRetCode == HttpStatusCode.Redirect) { //重定向 _param.url = response.Headers["Location"].Trim(); response.Close(); response = null; request.Abort(); request = null; try { file.Close(); } catch (Exception e) { Debug.LogWarning(e.Message); } Debug.Log("Redirect " + _param.url); _param.IsRedirect = true; ThreadFunc(_param); return; } else if (HttpRetCode == HttpStatusCode.GatewayTimeout || HttpRetCode == HttpStatusCode.RequestTimeout) { //net error response.Close(); response = null; request.Abort(); request = null; try { file.Close(); } catch (Exception e) { Debug.LogWarning(e.Message); } Debug.Log("timeout"); return; } else if (HttpRetCode == HttpStatusCode.OK || HttpRetCode == HttpStatusCode.Created || HttpRetCode == HttpStatusCode.Accepted || HttpRetCode == HttpStatusCode.NonAuthoritativeInformation || HttpRetCode == HttpStatusCode.NoContent || HttpRetCode == HttpStatusCode.ResetContent || HttpRetCode == HttpStatusCode.PartialContent) { if (HttpRetCode != HttpStatusCode.PartialContent) { //如果不是断点下载 或者服务器不支持 那么需要 重新下载完整文件 try { file.Close(); file = null; } catch (Exception e) { } try { Directory.Delete(_param.path_to_save, true); } catch (Exception e) { } try { Directory.CreateDirectory(_param.path_to_save); } catch (Exception e) { } file = File.Create(_param.path_to_save + "/" + _param.file_name); } } else { //req error response.Close(); response = null; request.Abort(); request = null; try { file.Close(); } catch (Exception e) { Debug.LogWarning(e.Message); } try { File.Delete(_param.path_to_save + "/" + _param.file_name); } catch (Exception e) { } Debug.LogWarning("error"); return; } //web 请求处理完成了 开始处理 接受数据了 long total_len = response.ContentLength; TotalSize = (int)total_len + (int)current_size; if (current_size < TotalSize) { if (current_size > 0) { // request.AddRange((int)current_size); CurrentSize = (int)current_size; } Stream web = request.GetResponse().GetResponseStream(); byte[] _cache = new byte[10240]; // 10kb int down_size = 0; int read_size = web.Read(_cache, 0, 10240); int total_read_size = 0; _Status = Status.Downloading; while (read_size > 0) { _Status = Status.Downloading; file.Write(_cache, 0, read_size); total_read_size += read_size; down_size += read_size; CurrentSize += read_size; // Debug.LogError("download ing " + CurrentSize + " " + TotalSize); file.Flush(); read_size = web.Read(_cache, 0, 10240); } file.Close(); file = null; web.Close(); web = null; response.Close(); response = null; request.Abort(); request = null; if (current_size + down_size < TotalSize) { //下载文件 长度不够 需要重新下载 Debug.LogWarning("file is smaller will re-try"); ThreadFunc(_param); return; } else if (current_size + down_size > TotalSize) { //下载的长度 超过了 实际长度 文件已经损坏 重新下载把 try { Directory.Delete(_param.path_to_save, true); } catch (Exception e) { Debug.LogWarning(e.Message); } Debug.LogWarning("file is bigger will delete and re-download"); ThreadFunc(_param); return; } else { //下载文件成功 开始校验MD5 _Status = Status.Verifying; string download_md5 = MD5Code.GetMD5HashFromFile(_param.path_to_save + "/" + _param.file_name); if (string.IsNullOrEmpty(_param.md5) == false && _param.md5 == download_md5) { //ok } else { if (_param.md5 != null) { Debug.LogWarning("excepted md5=" + _param.md5 + " file=" + download_md5); } //md5 verify error 尝试重新下载 try { file.Close(); file = null; response.Close(); response = null; request.Abort(); request = null; } catch (Exception e) { } try { Directory.Delete(_param.path_to_save, true); } catch (Exception e) { Debug.LogWarning(e.Message); } ThreadFunc(_param); return; } _Status = Status.OK; } } else if (current_size == total_len) {//当前文件和 服务器文件大小一样 默认为 下载完成 需要校验MD5 try { file.Close(); file = null; response.Close(); response = null; request.Abort(); request = null; } catch (Exception e) { } Debug.LogWarning("file is req just done"); _Status = Status.Verifying; var download_md5 = MD5Code.GetMD5HashFromFile(_param.path_to_save + "/" + _param.file_name); if (string.IsNullOrEmpty(_param.md5) == false && _param.md5 == download_md5) { //ok } else { if (_param.md5 != null) { Debug.LogWarning("1excepted md5=" + _param.md5 + " file=" + download_md5); } //md5 verify error 尝试重新下载 try { file.Close(); file = null; response.Close(); response = null; request.Abort(); request = null; } catch (Exception e) { } try { Directory.Delete(_param.path_to_save, true); } catch (Exception e) { Debug.LogWarning(e.Message); } ThreadFunc(_param); return; } _Status = Status.OK; } else { //当前文件超过了 大小 需要重新下载 try { Directory.Delete(_param.path_to_save, true); } catch (Exception e) { Debug.LogWarning(e.Message); } Debug.LogWarning("file is bigger will delete and re-download 2"); try { file.Close(); file = null; response.Close(); response = null; request.Abort(); request = null; } catch (Exception e) { } ThreadFunc(_param); return; } //走到了这里 都当作文件下载成功 并且校验成功 可以开始安装了 _Status = Status.OK; this.DownloadOK(); } catch (Exception ee) { //整个下载流程出了异常错误 Debug.LogWarning(ee.Message); _Status = Status.Checking; try { if (file != null) { file.Close(); file = null; } } catch (Exception e) { Debug.LogWarning(e.Message); } try { File.Delete(_param.path_to_save + "/" + _param.file_name); } catch (Exception e) { } ThreadFunc(_param); return; } } }
private async Task HandleDownloadAsync(bool start, DownloadParam downloadParameter) { try { // LogStatus("Running: " + download.Guid, NotifyType.StatusMessage); // Store the download so we can pause/resume. activeDownloads.Add(downloadParameter.downloadOperation); Progress<DownloadOperation> progressCallback = new Progress<DownloadOperation>(download => { double percent = 0; if (download.Progress.TotalBytesToReceive > 0) { percent = download.Progress.BytesReceived * 100 / download.Progress.TotalBytesToReceive; Debug.WriteLine("当前进度:{0}", percent); } if (percent != 100) { downloadParameter.downloadInfo.Status = DownloadStatus.Downloading; } else downloadParameter.downloadInfo.Status = DownloadStatus.Complete; downloadParameter.downloadInfo.DownProgress = percent; }); if (start) { await downloadParameter.downloadOperation.StartAsync().AsTask(downloadParameter.downloadInfo.Cts.Token, progressCallback); } else { await downloadParameter.downloadOperation.AttachAsync().AsTask(downloadParameter.downloadInfo.Cts.Token, progressCallback); } ResponseInformation response = downloadParameter.downloadOperation.GetResponseInformation(); } catch (Exception ex) { downloadParameter.downloadInfo.Status = DownloadStatus.Error; if (downloadParameter.downloadInfo.Cts != null && downloadParameter.downloadInfo.Cts.IsCancellationRequested == false) { downloadParameter.downloadInfo.Cts.Cancel(); downloadParameter.downloadInfo.Cts.Dispose(); } DeleteLocalFile(downloadParameter.downloadInfo); return; /* if (!IsExceptionHandled("Execution error", ex, downloadParameter.downloadOperation)) { throw; } * */ } finally { activeDownloads.Remove(downloadParameter.downloadOperation); if (downloadParameter.downloadInfo.Status == DownloadStatus.Complete) { Debug.WriteLine("Download <<" + downloadParameter.downloadInfo.Title + ">> Complete."); if (downloadingInfoList.Contains(downloadParameter.downloadInfo)) downloadingInfoList.Remove(downloadParameter.downloadInfo); if (!DownloadedListContains(downloadParameter.downloadInfo.Vid)) downloadedInfoList.Add(downloadParameter.downloadInfo); } } }
/* // Enumerate the downloads that were going on in the background while the app was closed. public async Task DiscoverActiveDownloadsAsync() { IReadOnlyList<DownloadOperation> downloads = null; try { downloads = await BackgroundDownloader.GetCurrentDownloadsAsync(); } catch (Exception ex) { if (!IsExceptionHandled("Discovery error", ex)) { throw; } return; } //Log("Loading background downloads: " + downloads.Count); if (downloads.Count > 0) { List<Task> tasks = new List<Task>(); foreach (DownloadOperation download in downloads) { //Log(String.Format(CultureInfo.CurrentCulture, "Discovered background download: {0}, Status: {1}", download.Guid, download.Progress.Status)); // Attach progress and completion handlers. DownloadInfo d = downloadingInfoList.Where(down => down.DownOperation == download).FirstOrDefault(); if (d != null) tasks.Add(HandleDownloadAsync(false, d)); } // Don't await HandleDownloadAsync() in the foreach loop since we would attach to the second // download only when the first one completed; attach to the third download when the second one // completes etc. We want to attach to all downloads immediately. // If there are actions that need to be taken once downloads complete, await tasks here, outside // the loop. await Task.WhenAll(tasks); } }*/ private async Task StartDownload(DownloadInfo downloadInfo) { downloadInfo.Status = DownloadStatus.Compare; Uri source; if (!Uri.TryCreate(downloadInfo.VideoUrl.Trim(), UriKind.Absolute, out source)) { downloadInfo.Status = DownloadStatus.UrlError; return; } string destination = downloadInfo.FileName; if (string.IsNullOrWhiteSpace(destination)) { downloadInfo.Status = DownloadStatus.NameNull; return; } StorageFile destinationFile; try { destinationFile = await Downloadfolder.CreateFileAsync( destination, CreationCollisionOption.ReplaceExisting); } catch { //rootPage.NotifyUser("Error while creating file: " + ex.Message, NotifyType.ErrorMessage); downloadInfo.Status = DownloadStatus.CreatFileError; ToolClass.DeleteExistedFile(Downloadfolder, destination); return; } BackgroundDownloader downloader = new BackgroundDownloader(); // downloader.CostPolicy = BackgroundTransferCostPolicy.Always; DownloadOperation download = downloader.CreateDownload(source, destinationFile); download.Priority = BackgroundTransferPriority.Default; downloadInfo.Cts = new CancellationTokenSource(); DownloadParam downloadParameter = new DownloadParam { downloadInfo = downloadInfo, downloadOperation = download }; // Attach progress and completion handlers. await HandleDownloadAsync(true, downloadParameter); }