/// <summary> /// Gathers a list of files to download for the update. /// </summary> private List <RemoteFileInfo> GatherFilesToDownload(string buildPath, string downloadDirectory) { List <RemoteFileInfo> filesToDownload = new List <RemoteFileInfo>(); // This could be multithreaded later on for faster processing, // calculating the SHA1 hashes can take a lot of time for (int i = 0; i < remoteBuildInfo.FileInfos.Count; i++) { var remoteFileInfo = remoteBuildInfo.FileInfos[i]; UpdateProgressChanged?.Invoke(this, new UpdateProgressEventArgs( UpdateProgressState.PREPARING, 0, (int)(i / (double)remoteBuildInfo.FileInfos.Count * 100.0), string.Empty)); if (!File.Exists(buildPath + remoteFileInfo.FilePath)) { if (!File.Exists(downloadDirectory + remoteFileInfo.FilePath)) { UpdaterLogger.Log("File " + remoteFileInfo.FilePath + " doesn't exist, adding it to the download queue."); filesToDownload.Add(remoteFileInfo); } else if (!HashHelper.FileHashMatches(downloadDirectory + remoteFileInfo.FilePath, remoteFileInfo.UncompressedHash)) { UpdaterLogger.Log("File " + remoteFileInfo.FilePath + " exists in the " + "temporary directory, but it's different from the remote version. Adding it to the download queue."); filesToDownload.Add(remoteFileInfo); } } else { if (!HashHelper.FileHashMatches(buildPath + remoteFileInfo.FilePath, remoteFileInfo.UncompressedHash)) { UpdaterLogger.Log("File " + remoteFileInfo.FilePath + " is different from the " + "remote version, adding it to the download queue."); filesToDownload.Add(remoteFileInfo); } else { UpdaterLogger.Log("File " + remoteFileInfo.FilePath + " is up to date."); } } } return(filesToDownload); }
private void VerifyFiles() { while (true) { IndexedRemoteFileInfo indexedFileInfo; if (stopped) { break; } lock (locker) { indexedFileInfo = filesToCheck[0]; } RemoteFileInfo fileInfo = indexedFileInfo.FileInfo; bool checkFileHash = true; if (fileInfo.Compressed) { try { CompressionHelper.DecompressFile(downloadDirectory + fileInfo.GetFilePathWithCompression(), downloadDirectory + fileInfo.FilePath); File.Delete(downloadDirectory + fileInfo.GetFilePathWithCompression()); } catch (Exception ex) { // The SevenZip compressor doesn't define what exceptions // it might throw, so we'll just catch them all UpdaterLogger.Log("Decompressing file " + fileInfo.FilePath + " failed! Message: " + ex.Message); VerificationFailed?.Invoke(this, new IndexEventArgs(indexedFileInfo.Index)); queueReady = false; checkFileHash = false; } } if (checkFileHash) { if (!HashHelper.FileHashMatches(downloadDirectory + fileInfo.FilePath, fileInfo.UncompressedHash)) { UpdaterLogger.Log("File " + fileInfo.FilePath + " failed verification!"); VerificationFailed?.Invoke(this, new IndexEventArgs(indexedFileInfo.Index)); queueReady = false; } else { UpdaterLogger.Log("File " + fileInfo.FilePath + " passed verification."); } } bool waitingForWork = false; lock (locker) { filesToCheck.RemoveAt(0); waitingForWork = filesToCheck.Count == 0; waitHandle.Reset(); if (queueReady && waitingForWork) { Completed?.Invoke(this, EventArgs.Empty); break; } //if (stopped) //{ // filesToCheck.Clear(); // break; //} } if (waitingForWork) { waitHandle.WaitOne(); } } lock (locker) { waitHandle.Dispose(); waitHandle = null; } // We could also dispose of verifierTask, but it sounds like we don't need to bother // https://blogs.msdn.microsoft.com/pfxteam/2012/03/25/do-i-need-to-dispose-of-tasks/ // In case we'd still want to do it, it'd be safest for this class to have a function // for disposing the task (maybe this class could implement IDisposable), and the // user of this class would then call it }