/// <inheritdoc /> public async Task <string> DownloadAsync(string packageFolder, IProgress <double>?progress, CancellationToken token = default) { // Wait for background sync operation. await _initialiseTask; using var tempDownloadDir = new TemporaryFolderAllocation(); using var tempExtractDir = new TemporaryFolderAllocation(); var tempDownloadPath = Path.Combine(tempDownloadDir.FolderPath, Path.GetRandomFileName()); var progressSlicer = new ProgressSlicer(progress); // Download Package var downloadSlice = progressSlicer.Slice(0.9f); await PackageResolver.DownloadPackageAsync(Version !, tempDownloadPath, new ReleaseMetadataVerificationInfo() { FolderPath = tempDownloadPath }, downloadSlice, token); // Extract package. var extractSlice = progressSlicer.Slice(0.1f); var archiveExtractor = new SevenZipSharpExtractor(); await archiveExtractor.ExtractPackageAsync(tempDownloadPath, tempExtractDir.FolderPath, extractSlice, token); // Copy all packages from download. return(WebDownloadablePackage.CopyPackagesFromExtractFolderToTargetDir(packageFolder, tempExtractDir.FolderPath, token)); }
/// <inheritdoc /> public async Task <string> DownloadAsync(string packageFolder, IProgress <double>?progress, CancellationToken token = default) { using var tempDownloadDirectory = new TemporaryFolderAllocation(); using var tempExtractDirectory = new TemporaryFolderAllocation(); var tempFilePath = Path.Combine(tempDownloadDirectory.FolderPath, Path.GetRandomFileName()); var progressSlicer = new ProgressSlicer(progress); // Start the modification download. using var httpClient = new HttpClient(); var downloadProgress = progressSlicer.Slice(0.9); await using var fileStream = new FileStream(tempFilePath, FileMode.OpenOrCreate); var archiveStream = await httpClient.GetStreamAsync(_url, token).ConfigureAwait(false); await archiveStream.CopyToAsyncEx(fileStream, 262144, downloadProgress, FileSize.GetValueOrDefault(1), token); if (token.IsCancellationRequested) { return(string.Empty); } /* Extract to Temp Directory */ var archiveExtractor = new SevenZipSharpExtractor(); var extractProgress = progressSlicer.Slice(0.1); await archiveExtractor.ExtractPackageAsync(tempFilePath, tempExtractDirectory.FolderPath, extractProgress, token); /* Get name of package. */ return(CopyPackagesFromExtractFolderToTargetDir(packageFolder, tempExtractDirectory.FolderPath, token)); }
/// <summary> /// Updates all of the mods. /// </summary> /// <param name="summary">Summary of updates returned from <see cref="GetUpdateDetailsAsync"/></param> /// <param name="progressHandler">Event to receive information about the overall download and extract progress of all mods combined.</param> public async Task Update(ModUpdateSummary summary, IProgress <double>?progressHandler = null) { // Guard against null. var progressMixer = new ProgressSlicer(progressHandler); var singleItemProgress = 1.0 / summary.ManagerModResultPairs.Count; for (var x = 0; x < summary.ManagerModResultPairs.Count; x++) { var slice = progressMixer.Slice(singleItemProgress); var pair = summary.ManagerModResultPairs[x]; var manager = pair.Manager; var version = pair.Result.LastVersion; await manager.PrepareUpdateAsync(version !, slice); await manager.StartUpdateAsync(version !, new OutOfProcessOptions(), new UpdateOptions() { CleanupAfterUpdate = true }); manager.Dispose(); } }
public async Task InstallReloadedAsync(string?installFolder = null, bool createShortcut = true, bool startReloaded = true) { // Step installFolder ??= Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), "Reloaded-II"); Directory.CreateDirectory(installFolder); using var tempDownloadDir = new TemporaryFolderAllocation(); var progressSlicer = new ProgressSlicer(new Progress <double>(d => { Progress = d * 100.0; })); try { var downloadLocation = Path.Combine(tempDownloadDir.FolderPath, $"Reloaded-II.zip"); // 0.15 CurrentStepNo = 0; await DownloadReloadedAsync(downloadLocation, progressSlicer.Slice(0.15)); if (CancellationToken.IsCancellationRequested) { throw new TaskCanceledException(); } // 0.20 CurrentStepNo = 1; await ExtractReloadedAsync(installFolder, downloadLocation, progressSlicer.Slice(0.05)); if (CancellationToken.IsCancellationRequested) { throw new TaskCanceledException(); } // 1.00 CurrentStepNo = 2; await CheckAndInstallMissingRuntimesAsync(installFolder, tempDownloadDir.FolderPath, progressSlicer.Slice(0.8), s => { CurrentStepDescription = s; }, CancellationToken.Token); var executableName = IntPtr.Size == 8 ? "Reloaded-II.exe" : "Reloaded-II32.exe"; var executablePath = Path.Combine(installFolder, executableName); var shortcutPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), "Reloaded-II.lnk"); if (createShortcut) { CurrentStepDescription = "Creating Shortcut"; MakeShortcut(shortcutPath, executablePath); } CurrentStepDescription = "All Set"; if (startReloaded) { Process.Start(executablePath); } } catch (TaskCanceledException) { IOEx.TryDeleteDirectory(installFolder); } catch (Exception e) { IOEx.TryDeleteDirectory(installFolder); MessageBox.Show("There was an error in installing Reloaded.\n" + $"Feel free to open an issue on github.com/Reloaded-Project/Reloaded-II if you require support.\n" + $"Message: {e.Message}\n" + $"Stack Trace: {e.StackTrace}", "Error in Installing Reloaded"); } }
/// <summary> /// [Requires Admin Permission] /// Finds all missing runtimes and silently installs them. /// </summary> /// <param name="urlSet">Set of all URLs and commandline arguments for the downloaded files. Obtained form running <see cref="GetMissingRuntimeUrls"/>.</param> /// <param name="downloadDirPath">Path to where the temporary runtimes should be downloaded to.</param> /// <param name="progress">Progress for the installation operation.</param> /// <param name="setCurrentStepDescription">Shows a description of the current runtime installation step.</param> /// <param name="token">Token allowing you to cancel the install task.</param> public static async Task DownloadAndInstallRuntimesAsync(HashSet <UrlCommandlinePair> urlSet, string downloadDirPath, IProgress <double> progress, Action <string> setCurrentStepDescription, CancellationToken token = default) { // Download Runtimes setCurrentStepDescription?.Invoke("Downloading & Installing Runtimes"); var progressSlicer = new ProgressSlicer(progress); var downloadSlice = progressSlicer.Slice(0.8f); var installSlice = progressSlicer.Slice(0.2f); var downloadQueue = new ConcurrentQueue <UrlCommandlinePair>(urlSet); var installQueue = new ConcurrentQueue <UrlCommandlinePair>(); // Start background download and install. var downloadTask = DownloadAllRuntimesAsync(); async Task DownloadAllRuntimesAsync() { var queueElements = downloadQueue.Count; var downloadSlicer = new ProgressSlicer(downloadSlice); int x = 0; while (downloadQueue.TryDequeue(out UrlCommandlinePair downloadLink)) { var client = new WebClient(); var downloadProgress = downloadSlicer.Slice(1.0 / queueElements); client.DownloadProgressChanged += (sender, args) => { downloadProgress.Report((float)args.BytesReceived / args.TotalBytesToReceive); }; var filePath = Path.Combine(downloadDirPath, $"Framework.{x++}.exe"); await client.DownloadFileTaskAsync(downloadLink.Url, filePath); if (token.IsCancellationRequested) { throw new TaskCanceledException(); } installQueue.Enqueue(new UrlCommandlinePair() { Parameters = downloadLink.Parameters, Url = filePath }); } } await Task.Run(InstallAllRuntimesAsync, token); async Task InstallAllRuntimesAsync() { var installSlicer = new ProgressSlicer(installSlice); var queueElements = urlSet.Count; loopstart: while (installQueue.TryDequeue(out UrlCommandlinePair runtimeInstallPath)) { var installProgress = installSlicer.Slice(1.0 / queueElements); ExecuteAsAdmin(runtimeInstallPath.Url, runtimeInstallPath.Parameters); installProgress.Report(1); } if (!downloadTask.IsCompleted) { await Task.Delay(100); goto loopstart; } } progress.Report(1); }