private Task<long> RunAllSyncItems(CancellationTokenSource cts) { string basePath = RootPath; /* Cleanup leftover files from a forced abort. */ if (Directory.Exists(TmpPath)) { var di = new DirectoryInfo(TmpPath).GetFiles("*", SearchOption.TopDirectoryOnly); foreach (var tmpfile in di) { OnDownloadMessage(Text.t("sync_deleting_leftovers_tmp", tmpfile.Name), true); File.Delete(tmpfile.FullName); } } Directory.CreateDirectory(TmpPath); var updaterBinaryLastWriteTimeBefore = new FileInfo(Assembly.GetExecutingAssembly().Location).LastWriteTime; var info = new DownloadStatusInfo(); info.globalFileTotal = Status.directoryCountToVerify + Status.fileCountToVerify; info.globalFileCurrent = 0; info.globalBytesTotal = Status.maxBytesToVerify; var toCheck = verifyUpdateFull ? LatestManifest.sync.Where((syncItem) => !(syncItem.ignoreExisting.GetValueOrDefault() && (File.Exists(syncItem.name) || Directory.Exists(syncItem.name)))) : (Status.filesToVerify.Concat(Status.directoriesToVerify)); /*var globalFileTotalStart = verifyUpdateFull ? LatestManifest.sync.Select(syncItem => syncItem.count > 0 ? syncItem.count : 1).Sum() : Status.fileCountToVerify;*/ var globalBytesTotalStart = verifyUpdateFull ? LatestManifest.sync.Select(syncItem => syncItem.size).Sum() : info.globalBytesTotal; return Task<long>.Factory.StartNew(delegate() { long bytesTotalPrev = 0; foreach (Manifest.SyncItem f in toCheck) { info.currentFile = f.name; bool lastHashFailed = false; string lastHashFileFailed = ""; string lastHashFailedMessage = ""; var t = RunSyncItem(f, verifyUpdateFull, Simulate, delegate(string fname, int percentage, long bytesReceived, long bytesTotal, long bytesPerSecond, string details) { if (bytesReceived > -1) info.currentBytes = bytesReceived; if (bytesTotal > -1) info.currentTotalBytes = bytesTotal; if (bytesPerSecond > -1) info.currentBps = bytesPerSecond; info.currentPercentage = ((float)percentage) / 100.0; info.currentPercentage = info.currentPercentage.Clamp(0, 1); info.details = details; if (fname != info.currentFile) { info.globalBytesCurrent += bytesTotalPrev; bytesTotalPrev = bytesTotal; info.globalFileCurrent++; info.currentFile = fname; } UpdateStatus(true); info.globalFileTotal = Status.fileCountToVerify; var bytesDone = info.globalBytesCurrent + bytesReceived; info.globalPercentage = globalBytesTotalStart > 0 ? (bytesDone / (globalBytesTotalStart / 100.0)) / 100 : 1; info.globalPercentage = info.globalPercentage.Clamp(0, 1); OnDownloadStatusInfoChanged(info); }, delegate(bool wasError, string str, long bytesOnNetwork) { if (wasError) { throw new Exception(str); } UpdateStatus(); info.currentFile = null; info.currentBytesOnNetwork += bytesOnNetwork; OnDownloadStatusInfoChanged(info); }, delegate(string message, bool show) { OnDownloadMessage(message, show); }, delegate(string file, string hash) { if (lastHashFailed) return false; lastHashFileFailed = file; // Do not error hard on missing manifest hashes, since that can be trusted // due to gpg signing. if (f.hashes == null || !f.hashes.ContainsKey(file.ToLowerInvariant())) { OnDownloadMessage(Text.t("sync_hash_no_hash", file), false); return true; } if (hash != f.hashes[file.ToLowerInvariant()]) { lastHashFailed = true; lastHashFailedMessage = Text.t("sync_hash_comparison_failed", file.ToLowerInvariant(), f.hashes[file.ToLowerInvariant()], hash); OnDownloadMessage(lastHashFailedMessage, false); return false; } OnDownloadMessage(Text.t("sync_hash_ok", file, f.hashes[file.ToLowerInvariant()]), false); return true; }, cts); try { t.Wait(); } catch (System.AggregateException x) { if (lastHashFailed) { OnDownloadMessage(Text.t("sync_hash_failed"), true); throw new Exception(Text.t("sync_hash_failed_long", lastHashFileFailed, lastHashFailedMessage)); } if (x.InnerException is TaskCanceledException) { OnDownloadMessage(Text.t("status_cancelled"), true); break; } else throw x; } var ret = t.Result; // Verify hashes // Security.VerifyHashes(f.hashes) /*foreach (KeyValuePair<string, string> entry in f.hashes) { // key = filename, value = md5 hash string OnDownloadMessage("Verifying checksum of " + entry.Key, false); var ourHash = Security.HashMD5(rootPath + "/" + entry.Key); if (ourHash.ToLowerInvariant() != entry.Value.ToLowerInvariant()) throw new Exception("verify: " + entry.Key + "=" + entry.Value + " vs " + ourHash); }*/ if (cts.IsCancellationRequested) { OnDownloadMessage(Text.t("status_cancelled"), true); break; } // This is a really ugly hackyhack to check if running binary was touched while we were upating. // We just ASSUME that the binary was touched by the sync itself. var updaterBinaryLastWriteTimeAfter = new FileInfo(Assembly.GetExecutingAssembly().Location).LastWriteTime; if (Math.Abs((updaterBinaryLastWriteTimeAfter - updaterBinaryLastWriteTimeBefore).TotalSeconds) > 1) { RequireRestart = true; break; } info.globalPercentage = globalBytesTotalStart > 0 ? (info.globalBytesCurrent / (globalBytesTotalStart / 100.0)) / 100 : 1; info.globalPercentage = info.globalPercentage.Clamp(0, 1); OnDownloadStatusInfoChanged(info); } return info.currentBytesOnNetwork; }, cts.Token); }
private Task<long> RunAllSyncItems(CancellationTokenSource cts) { string basePath = RootPath; /* Cleanup leftover files from a forced abort. */ if (Directory.Exists(TmpPath)) { var di = new DirectoryInfo(TmpPath).GetFiles("*", SearchOption.TopDirectoryOnly); foreach (var tmpfile in di) { OnDownloadMessage("<apagando restos de um cancelamento: " + tmpfile.Name + ">", true); File.Delete(tmpfile.FullName); } } Directory.CreateDirectory(TmpPath); var updaterBinaryLastWriteTimeBefore = new FileInfo(Assembly.GetExecutingAssembly().Location).LastWriteTime; var info = new DownloadStatusInfo(); info.globalFileTotal = Status.directoryCountToVerify + Status.fileCountToVerify; info.globalFileCurrent = 0; info.globalBytesTotal = Status.maxBytesToVerify; var toCheck = verifyUpdateFull ? LatestManifest.sync.Where((syncItem) => !(syncItem.ignoreExisting.GetValueOrDefault() && (File.Exists(syncItem.name) || Directory.Exists(syncItem.name)))) : (Status.filesToVerify.Concat(Status.directoriesToVerify)); /*var globalFileTotalStart = verifyUpdateFull ? LatestManifest.sync.Select(syncItem => syncItem.count > 0 ? syncItem.count : 1).Sum() : Status.fileCountToVerify;*/ var globalBytesTotalStart = verifyUpdateFull ? LatestManifest.sync.Select(syncItem => syncItem.size).Sum() : info.globalBytesTotal; return Task<long>.Factory.StartNew(delegate() { long bytesTotalPrev = 0; foreach (Manifest.SyncItem f in toCheck) { info.currentFile = f.name; // Hacky: Make sure we can write to our target. This is mostly due to rsync // sometimes setting "ReadOnly" on .exe files when the remote is configured // not quite correctly and only affects updating the updater itself. try { // new FileInfo(rootPath + "/" + f.name) {IsReadOnly = false}.Refresh(); EnsureWriteable(RootPath + "/" + f.name); } catch (Exception e) { } var t = RunSyncItem(f, verifyUpdateFull, Simulate, delegate(string fname, int percentage, long bytesReceived, long bytesTotal, long bytesPerSecond) { if (bytesReceived > -1) info.currentBytes = bytesReceived; if (bytesTotal > -1) info.currentTotalBytes = bytesTotal; if (bytesPerSecond > -1) info.currentBps = bytesPerSecond; info.currentPercentage = bytesTotal > 0 ? (bytesReceived / (bytesTotal / 100.0)) / 100 : 0; if (fname != info.currentFile) { info.globalBytesCurrent += bytesTotalPrev; bytesTotalPrev = bytesTotal; info.globalFileCurrent++; info.currentFile = fname; } UpdateStatus(true); info.globalFileTotal = Status.fileCountToVerify; var bytesDone = info.globalBytesCurrent + bytesReceived; info.globalPercentage = globalBytesTotalStart > 0 ? (bytesDone / (globalBytesTotalStart / 100.0)) / 100 : 1; info.globalPercentage = info.globalPercentage.Clamp(0, 1); OnDownloadStatusInfoChanged(info); }, delegate(bool wasError, string str, long bytesOnNetwork) { if (wasError) { throw new Exception(str); } UpdateStatus(); info.currentFile = null; info.currentBytesOnNetwork += bytesOnNetwork; OnDownloadStatusInfoChanged(info); }, delegate(string message, bool show) { OnDownloadMessage(message, show); }, cts); try { t.Wait(); } catch (System.AggregateException x) { if (x.InnerException is TaskCanceledException) { break; } else throw x; } var ret = t.Result; if (cts.IsCancellationRequested) break; // This is a really ugly hackyhack to check if running binary was touched while we were upating. // We just ASSUME that the binary was touched by the sync itself. var updaterBinaryLastWriteTimeAfter = new FileInfo(Assembly.GetExecutingAssembly().Location).LastWriteTime; if (Math.Abs((updaterBinaryLastWriteTimeAfter - updaterBinaryLastWriteTimeBefore).TotalSeconds) > 1) { RequireRestart = true; break; } info.globalPercentage = globalBytesTotalStart > 0 ? (info.globalBytesCurrent / (globalBytesTotalStart / 100.0)) / 100 : 1; info.globalPercentage = info.globalPercentage.Clamp(0, 1); OnDownloadStatusInfoChanged(info); } return info.currentBytesOnNetwork; }, cts.Token); }
private Task <long> RunAllSyncItems(CancellationTokenSource cts) { string basePath = RootPath; /* Cleanup leftover files from a forced abort. */ if (Directory.Exists(TmpPath)) { var di = new DirectoryInfo(TmpPath).GetFiles("*", SearchOption.TopDirectoryOnly); foreach (var tmpfile in di) { OnDownloadMessage("<apagando restos de um cancelamento: " + tmpfile.Name + ">", true); File.Delete(tmpfile.FullName); } } Directory.CreateDirectory(TmpPath); var updaterBinaryLastWriteTimeBefore = new FileInfo(Assembly.GetExecutingAssembly().Location).LastWriteTime; var info = new DownloadStatusInfo(); info.globalFileTotal = Status.directoryCountToVerify + Status.fileCountToVerify; info.globalFileCurrent = 0; info.globalBytesTotal = Status.maxBytesToVerify; var toCheck = verifyUpdateFull ? LatestManifest.sync.Where((syncItem) => !(syncItem.ignoreExisting.GetValueOrDefault() && (File.Exists(syncItem.name) || Directory.Exists(syncItem.name)))) : (Status.filesToVerify.Concat(Status.directoriesToVerify)); /*var globalFileTotalStart = verifyUpdateFull ? * LatestManifest.sync.Select(syncItem => syncItem.count > 0 ? syncItem.count : 1).Sum() : * Status.fileCountToVerify;*/ var globalBytesTotalStart = verifyUpdateFull ? LatestManifest.sync.Select(syncItem => syncItem.size).Sum() : info.globalBytesTotal; return(Task <long> .Factory.StartNew(delegate() { long bytesTotalPrev = 0; foreach (Manifest.SyncItem f in toCheck) { info.currentFile = f.name; // Hacky: Make sure we can write to our target. This is mostly due to rsync // sometimes setting "ReadOnly" on .exe files when the remote is configured // not quite correctly and only affects updating the updater itself. try { // new FileInfo(rootPath + "/" + f.name) {IsReadOnly = false}.Refresh(); EnsureWriteable(RootPath + "/" + f.name); } catch (Exception e) { } var t = RunSyncItem(f, verifyUpdateFull, Simulate, delegate(string fname, int percentage, long bytesReceived, long bytesTotal, long bytesPerSecond) { if (bytesReceived > -1) { info.currentBytes = bytesReceived; } if (bytesTotal > -1) { info.currentTotalBytes = bytesTotal; } if (bytesPerSecond > -1) { info.currentBps = bytesPerSecond; } info.currentPercentage = bytesTotal > 0 ? (bytesReceived / (bytesTotal / 100.0)) / 100 : 0; if (fname != info.currentFile) { info.globalBytesCurrent += bytesTotalPrev; bytesTotalPrev = bytesTotal; info.globalFileCurrent++; info.currentFile = fname; } UpdateStatus(true); info.globalFileTotal = Status.fileCountToVerify; var bytesDone = info.globalBytesCurrent + bytesReceived; info.globalPercentage = globalBytesTotalStart > 0 ? (bytesDone / (globalBytesTotalStart / 100.0)) / 100 : 1; info.globalPercentage = info.globalPercentage.Clamp(0, 1); OnDownloadStatusInfoChanged(info); }, delegate(bool wasError, string str, long bytesOnNetwork) { if (wasError) { throw new Exception(str); } UpdateStatus(); info.currentFile = null; info.currentBytesOnNetwork += bytesOnNetwork; OnDownloadStatusInfoChanged(info); }, delegate(string message, bool show) { OnDownloadMessage(message, show); }, cts); try { t.Wait(); } catch (System.AggregateException x) { if (x.InnerException is TaskCanceledException) { break; } else { throw x; } } var ret = t.Result; if (cts.IsCancellationRequested) { break; } // This is a really ugly hackyhack to check if running binary was touched while we were upating. // We just ASSUME that the binary was touched by the sync itself. var updaterBinaryLastWriteTimeAfter = new FileInfo(Assembly.GetExecutingAssembly().Location).LastWriteTime; if (Math.Abs((updaterBinaryLastWriteTimeAfter - updaterBinaryLastWriteTimeBefore).TotalSeconds) > 1) { RequireRestart = true; break; } info.globalPercentage = globalBytesTotalStart > 0 ? (info.globalBytesCurrent / (globalBytesTotalStart / 100.0)) / 100 : 1; info.globalPercentage = info.globalPercentage.Clamp(0, 1); OnDownloadStatusInfoChanged(info); } return info.currentBytesOnNetwork; }, cts.Token)); }