/// <summary> /// Checks the files provided in the given <see cref="VersionFileList"/> and compares them to the local files /// to see what files need to be updated. /// </summary> /// <param name="vfl">The <see cref="VersionFileList"/> containing the files to be updated.</param> /// <returns>The relative paths to the files that need to be updated.</returns> IEnumerable <string> FindFilesToUpdate(VersionFileList vfl) { var ret = new List <string>(); // Loop through each file foreach (var updateFileInfo in vfl.Files) { // Get the local file path var localFilePath = PathHelper.CombineDifferentPaths(Settings.TargetPath, updateFileInfo.FilePath); // If the file does not exist, add it if (!File.Exists(localFilePath)) { ret.Add(updateFileInfo.FilePath); continue; } // Get the info for the local file try { var localFileInfo = new FileInfo(localFilePath); // If the size of the local file doesn't equal the size of the updated file, avoid // checking the hash and just update it if (localFileInfo.Length != updateFileInfo.Size) { if (log.IsDebugEnabled) { log.DebugFormat( "Update check on file `{0}`: File needs update - size mismatch (current: {1}, expected: {2}).", updateFileInfo.FilePath, localFileInfo.Length, updateFileInfo.Size); } ret.Add(updateFileInfo.FilePath); continue; } // File exists and is of the correct size, so compare the hash of the local file to the expected hash var localFileHash = Hasher.GetFileHash(localFilePath); if (!StringComparer.Ordinal.Equals(localFileHash, updateFileInfo.Hash)) { if (log.IsDebugEnabled) { log.DebugFormat( "Update check on file `{0}`: File needs update - hash mismatch (current: {1}, expected: {2}).", updateFileInfo.FilePath, localFileHash, updateFileInfo.Hash); } ret.Add(updateFileInfo.FilePath); continue; } } catch (IOException ex) { const string errmsg = "Failed to analyze file `{0}` to see if it needs to be updated. Will assume update is required. Exception: {1}"; if (log.IsErrorEnabled) { log.ErrorFormat(errmsg, updateFileInfo.FilePath, ex); } Debug.Fail(string.Format(errmsg, updateFileInfo.FilePath, ex)); // On an IOException, assume the file needs to be updated ret.Add(updateFileInfo.FilePath); continue; } if (log.IsDebugEnabled) { log.DebugFormat("Update check on file `{0}`: file is up-to-date.", updateFileInfo.FilePath); } } if (log.IsInfoEnabled) { log.InfoFormat("Found `{0}` files needing to be updated.", ret.Count); } return(ret); }