public override void Prepare(Sources.IUpdateSource source) { if (string.IsNullOrEmpty(LocalPath)) { UpdateManager.Instance.Logger.Log(Logger.SeverityLevel.Warning, "FileUpdateTask: LocalPath is empty, task is a noop"); return; // Errorneous case, but there's nothing to prepare to, and by default we prefer a noop over an error } string fileName; if (!string.IsNullOrEmpty(UpdateTo)) fileName = UpdateTo; else fileName = LocalPath; _tempFile = null; string baseUrl = UpdateManager.Instance.BaseUrl; string tempFileLocal = Path.Combine(UpdateManager.Instance.Config.TempFolder, Guid.NewGuid().ToString()); UpdateManager.Instance.Logger.Log("FileUpdateTask: Downloading {0} with BaseUrl of {1} to {2}", fileName, baseUrl, tempFileLocal); if (!source.GetData(fileName, baseUrl, OnProgress, ref tempFileLocal)) throw new UpdateProcessFailedException("FileUpdateTask: Failed to get file from source"); _tempFile = tempFileLocal; if (_tempFile == null) throw new UpdateProcessFailedException("FileUpdateTask: Failed to get file from source"); if (!string.IsNullOrEmpty(Sha256Checksum)) { string checksum = Utils.FileChecksum.GetSHA256Checksum(_tempFile); if (!checksum.Equals(Sha256Checksum)) throw new UpdateProcessFailedException(string.Format("FileUpdateTask: Checksums do not match; expected {0} but got {1}", Sha256Checksum, checksum)); } _destinationFile = Path.Combine(Path.GetDirectoryName(UpdateManager.Instance.ApplicationPath), LocalPath); UpdateManager.Instance.Logger.Log("FileUpdateTask: Prepared successfully; destination file: {0}", _destinationFile); }
public bool Prepare(Sources.IUpdateSource source) { if (string.IsNullOrEmpty(LocalPath)) return true; // Errorneous case, but there's nothing to prepare to... string fileName; if (!string.IsNullOrEmpty(UpdateTo)) fileName = UpdateTo; else fileName = LocalPath; tempFile = null; try { string tempFileLocal = Path.Combine(UpdateManager.Instance.TempFolder, Guid.NewGuid().ToString()); if (!source.GetData(fileName, UpdateManager.Instance.BaseUrl, ref tempFileLocal)) return false; tempFile = tempFileLocal; } catch (Exception ex) { throw new UpdateProcessFailedException("Couldn't get Data from source", ex); } if (!string.IsNullOrEmpty(Sha256Checksum)) { string checksum = Utils.FileChecksum.GetSHA256Checksum(tempFile); if (!checksum.Equals(Sha256Checksum)) return false; } return true; }
/// <summary> /// Do all work, especially if it is lengthy, required to prepare the update task, except from /// the final trivial operations required to actually perform the update. /// </summary> /// <param name="source">An update source object, in case more data is required</param> /// <returns>True if successful, false otherwise</returns> public bool Prepare(Sources.IUpdateSource source) { if (string.IsNullOrEmpty(UpdateTo)) return false; // Clear temp folder if (Directory.Exists(updateDirectory)) { try { Directory.Delete(updateDirectory, true); } catch { } } Directory.CreateDirectory(updateDirectory); // Download the zip to a temp file that is deleted automatically when the app exits string zipLocation = null; try { if (!source.GetData(UpdateTo, string.Empty, ref zipLocation)) return false; } catch (Exception ex) { throw new UpdateProcessFailedException("Couldn't get Data from source", ex); } if (!string.IsNullOrEmpty(Sha256Checksum)) { string checksum = Utils.FileChecksum.GetSHA256Checksum(zipLocation); if (!checksum.Equals(Sha256Checksum)) return false; } if (string.IsNullOrEmpty(zipLocation)) return false; // Unzip to temp folder; no need to delete the zip file as this will be done by the OS filesList = new List<string>(); ZipFile zf = null; try { FileStream fs = File.OpenRead(zipLocation); zf = new ZipFile(fs); foreach (ZipEntry zipEntry in zf) { if (!zipEntry.IsFile) { continue; // Ignore directories } String entryFileName = zipEntry.Name; // to remove the folder from the entry:- entryFileName = Path.GetFileName(entryFileName); // Optionally match entrynames against a selection list here to skip as desired. // The unpacked length is available in the zipEntry.Size property. byte[] buffer = new byte[4096]; // 4K is optimum Stream zipStream = zf.GetInputStream(zipEntry); // Manipulate the output filename here as desired. String fullZipToPath = Path.Combine(updateDirectory, entryFileName); string directoryName = Path.GetDirectoryName(fullZipToPath); if (directoryName.Length > 0) Directory.CreateDirectory(directoryName); // Unzip file in buffered chunks. This is just as fast as unpacking to a buffer the full size // of the file, but does not waste memory. // The "using" will close the stream even if an exception occurs. using (FileStream streamWriter = File.Create(fullZipToPath)) { StreamUtils.Copy(zipStream, streamWriter, buffer); } filesList.Add(entryFileName); } return true; } catch (Exception ex) { throw new UpdateProcessFailedException("Couldn't get unzip data", ex); } finally { if (zf != null) { zf.IsStreamOwner = true; // Makes close also shut the underlying stream zf.Close(); // Ensure we release resources } } }