/// <summary> /// Signs a number of <see cref="Feed"/>s with a single <see cref="OpenPgpSecretKey"/>. /// </summary> /// <param name="secretKey">The private key to use for signing the files.</param> /// <param name="passphrase">The passphrase to use to unlock the key.</param> /// <exception cref="IOException">The feed file could not be read or written.</exception> /// <exception cref="UnauthorizedAccessException">Read or write access to the feed file is not permitted.</exception> private void SignFiles(OpenPgpSecretKey?secretKey, string passphrase) { var task = ForEachTask.Create(Resources.SigningFeeds, _files, file => { SignedFeed signedFeed; try { signedFeed = SignedFeed.Load(file.FullName); } #region Error handling catch (Exception ex) when(ex is UnauthorizedAccessException or InvalidDataException) { // Wrap exception since only certain exception types are allowed throw new IOException(ex.Message, ex); } #endregion signedFeed.SecretKey = secretKey; try { signedFeed.Save(file.FullName, passphrase); } #region Error handling catch (Exception ex) when(ex is UnauthorizedAccessException or KeyNotFoundException or WrongPassphraseException) { // Wrap exception since only certain exception types are allowed throw new IOException(ex.Message, ex); } #endregion });
/// <inheritdoc /> public void Purge(ITaskHandler handler) { #region Sanity checks if (handler == null) { throw new ArgumentNullException(nameof(handler)); } #endregion var paths = Directory.GetDirectories(Path).Where(path => { var digest = new ManifestDigest(); digest.TryParse(System.IO.Path.GetFileName(path)); return(digest.AvailableDigests.Any()); }).ToList(); if (paths.Count == 0) { return; } if (MissingAdminRights) { throw new NotAdminException(Resources.MustBeAdminToRemove); } handler.RunTask(ForEachTask.Create( name: string.Format(Resources.DeletingDirectory, Path), target: paths, work: path => RemoveInner(path, handler, allowAutoShutdown: true))); RemoveDeleteInfoFile(); }
/// <inheritdoc/> public long Optimise(ITaskHandler handler) { #region Sanity checks if (handler == null) { throw new ArgumentNullException(nameof(handler)); } #endregion if (!Directory.Exists(Path)) { return(0); } if (MissingAdminRights) { throw new NotAdminException(); } using var run = new OptimiseRun(Path); handler.RunTask(ForEachTask.Create( name: string.Format(Resources.FindingDuplicateFiles, Path), target: ListAll(), work: run.Work)); return(run.SavedBytes); }
/// <inheritdoc/> public virtual long Optimise(ITaskHandler handler) { #region Sanity checks if (handler == null) { throw new ArgumentNullException(nameof(handler)); } #endregion if (!Directory.Exists(DirectoryPath)) { return(0); } if (Kind == ImplementationStoreKind.ReadOnly && !WindowsUtils.IsAdministrator) { throw new NotAdminException(Resources.MustBeAdminToOptimise); } using var run = new OptimiseRun(DirectoryPath); handler.RunTask(ForEachTask.Create( name: string.Format(Resources.FindingDuplicateFiles, DirectoryPath), target: ListAll(), work: run.Work)); return(run.SavedBytes); }
internal ForEachTask(ForEachTask <S, T> parent, Spliterator <S> spliterator) : base(parent) { this.Spliterator = spliterator; this.Sink = parent.Sink; this.TargetSize = parent.TargetSize; this.Helper = parent.Helper; }
public override ExitCode Execute() { var store = GetEffectiveStore(); Handler.RunTask(ForEachTask.Create( name: Resources.StoreAudit, target: store.ListAll().ToList(), work: digest => store.Verify(digest, Handler))); return(ExitCode.OK); }
private void CleanImplementations(IEnumerable <ImplementationSelection> implementations) { var digestsToKeep = implementations.Select(x => x.ManifestDigest); var digestsToRemove = ImplementationStore.ListAll().Except(digestsToKeep, ManifestDigestPartialEqualityComparer.Instance); Handler.RunTask(ForEachTask.Create( name: Resources.RemovingOutdated, target: digestsToRemove.ToList(), work: digest => ImplementationStore.Remove(digest, Handler))); }
public void TestCallback() { var target = new[] {"element1", "element2", "element2"}; var calledFor = new List<string>(); var task = new ForEachTask<string>("Test task", target, calledFor.Add); task.Run(); calledFor.Should().Equal(target); }
/// <summary> /// Signs a number of <see cref="Feed"/>s with a single <see cref="OpenPgpSecretKey"/>. /// </summary> /// <param name="secretKey">The private key to use for signing the files.</param> /// <param name="passphrase">The passphrase to use to unlock the key.</param> /// <exception cref="IOException">The feed file could not be read or written.</exception> /// <exception cref="UnauthorizedAccessException">Read or write access to the feed file is not permitted.</exception> private void SignFiles(OpenPgpSecretKey secretKey, string passphrase) { var task = ForEachTask.Create("Signing feeds", _files, file => { SignedFeed signedFeed; try { signedFeed = SignedFeed.Load(file.FullName); } #region Error handling catch (UnauthorizedAccessException ex) { // Wrap exception since only certain exception types are allowed throw new IOException(ex.Message, ex); } catch (InvalidDataException ex) { // Wrap exception since only certain exception types are allowed throw new IOException(ex.Message + (ex.InnerException == null ? "" : Environment.NewLine + ex.InnerException.Message), ex); } #endregion signedFeed.SecretKey = secretKey; try { signedFeed.Save(file.FullName, passphrase); } #region Error handling catch (UnauthorizedAccessException ex) { // Wrap exception since only certain exception types are allowed throw new IOException(ex.Message, ex); } catch (KeyNotFoundException ex) { // Wrap exception since only certain exception types are allowed throw new IOException(ex.Message, ex); } catch (WrongPassphraseException ex) { // Wrap exception since only certain exception types are allowed throw new IOException(ex.Message, ex); } #endregion }); using (var handler = new DialogTaskHandler(this)) handler.RunTask(task); Msg.Inform(this, "Successfully signed files.", MsgSeverity.Info); }
/// <inheritdoc/> public override ExitCode Execute() { if (!Handler.Ask(Resources.ConfirmRemoveAll, defaultAnswer: true)) { return(ExitCode.NoChanges); } using var integrationManager = new IntegrationManager(Config, Handler, MachineWide); Handler.RunTask(ForEachTask.Create(Resources.RemovingApplications, integrationManager.AppList.Entries.ToList(), integrationManager.RemoveApp)); // Purge sync status, otherwise next sync would remove everything from server as well instead of restoring from there File.Delete(AppList.GetDefaultPath(MachineWide) + SyncIntegrationManager.AppListLastSyncSuffix); return(ExitCode.OK); }
/// <summary> /// Removes all applications from the <see cref="AppList"/> and undoes any desktop environment integration. /// </summary> /// <param name="handler">A callback object used when the the user is to be informed about the progress of long-running operations such as downloads.</param> /// <param name="machineWide">Apply the operation machine-wide instead of just for the current user.</param> public static void RemoveAllApps(ITaskHandler handler, bool machineWide) { #region Sanity checks if (handler == null) { throw new ArgumentNullException(nameof(handler)); } #endregion using (var integrationManager = new IntegrationManager(handler, machineWide)) { handler.RunTask(ForEachTask.Create(Resources.RemovingApplications, integrationManager.AppList.Entries.ToList(), integrationManager.RemoveApp)); // Purge sync status, otherwise next sync would remove everything from server as well instead of restoring from there File.Delete(AppList.GetDefaultPath(machineWide) + SyncIntegrationManager.AppListLastSyncSuffix); } }
/// <inheritdoc/> protected override void OnStage() { _pendingDirectoryDeletes.Push(Path); var filesToDelete = new List <string>(); string manifestPath = System.IO.Path.Combine(Path, Manifest.ManifestFile); if (File.Exists(manifestPath)) { filesToDelete.Add(manifestPath); } foreach (var pair in ElementPaths) { string elementPath = System.IO.Path.Combine(Path, pair.Key); if (pair.Value is ManifestDirectory) { if (Directory.Exists(elementPath)) { _pendingDirectoryDeletes.Push(elementPath); } } else { if (File.Exists(elementPath)) { filesToDelete.Add(elementPath); } } } if (filesToDelete.Count != 0) { UnlockFiles(filesToDelete); Handler.RunTask(ForEachTask.Create(Resources.DeletingObsoleteFiles, filesToDelete, path => { string tempPath = Randomize(path); File.Move(path, tempPath); _pendingFilesDeletes.Push(new KeyValuePair <string, string>(path, tempPath)); })); } }
// Similar to AbstractTask but doesn't need to track child tasks public void Compute() { Spliterator <S> rightSplit = Spliterator, leftSplit; long sizeEstimate = rightSplit.EstimateSize(), sizeThreshold; if ((sizeThreshold = TargetSize) == 0L) { TargetSize = sizeThreshold = AbstractTask.SuggestTargetSize(sizeEstimate); } bool isShortCircuit = StreamOpFlag.SHORT_CIRCUIT.isKnown(Helper.StreamAndOpFlags); bool forkRight = false; Sink <S> taskSink = Sink; ForEachTask <S, T> task = this; while (!isShortCircuit || !taskSink.cancellationRequested()) { if (sizeEstimate <= sizeThreshold || (leftSplit = rightSplit.TrySplit()) == null) { task.Helper.CopyInto(taskSink, rightSplit); break; } ForEachTask <S, T> leftTask = new ForEachTask <S, T>(task, leftSplit); task.AddToPendingCount(1); ForEachTask <S, T> taskToFork; if (forkRight) { forkRight = false; rightSplit = leftSplit; taskToFork = task; task = leftTask; } else { forkRight = true; taskToFork = leftTask; } taskToFork.Fork(); sizeEstimate = rightSplit.EstimateSize(); } task.Spliterator = null; task.PropagateCompletion(); }
/// <summary> /// Runs ngen in the background to pre-compile new/updated .NET assemblies. /// </summary> private void NgenApply() { if (!WindowsUtils.IsWindows) { return; } if (!File.Exists(_ngenExe)) { return; } Handler.RunTask(ForEachTask.Create(Resources.RunNgen, _ngenAssemblies, assembly => { string arguments = new[] { "install", Path.Combine(TargetDir, assembly), "/queue" }.JoinEscapeArguments(); new ProcessStartInfo(_ngenExe, arguments) { WindowStyle = ProcessWindowStyle.Hidden }.Run(); })); }
private void CleanImplementations(IEnumerable <ImplementationSelection> implementations) { var digestsToKeep = implementations.Select(x => x.ManifestDigest); var digestsToRemove = ImplementationStore.ListAll().Except(digestsToKeep, ManifestDigestPartialEqualityComparer.Instance); Handler.RunTask(ForEachTask.Create( name: Resources.RemovingOutdated, target: digestsToRemove.ToList(), work: digest => { try { ImplementationStore.Remove(digest, Handler); } catch (NotAdminException ex) when(ZeroInstallInstance.IsLibraryMode) { Log.Info($"Unable to remove {digest}", ex); } } )); }
/// <inheritdoc /> public void Purge(ITaskHandler handler) { #region Sanity checks if (handler == null) { throw new ArgumentNullException(nameof(handler)); } #endregion ThrowIfMissingAdminRights(); var paths = Directory.GetDirectories(Path).Where(path => { var digest = new ManifestDigest(); digest.ParseID(System.IO.Path.GetFileName(path)); return(digest.Best != null); }).ToList(); handler.RunTask(ForEachTask.Create( name: string.Format(Resources.DeletingDirectory, Path), target: paths, work: digest => RemoveInner(digest, handler, purge: true))); }
/// <inheritdoc/> public void Repair(Converter <FeedUri, Feed> feedRetriever) { #region Sanity checks if (feedRetriever == null) { throw new ArgumentNullException(nameof(feedRetriever)); } #endregion try { Handler.RunTask(ForEachTask.Create(Resources.RepairingIntegration, AppList.Entries, x => RepairAppInternal(x, feedRetriever(x.InterfaceUri)))); } catch (KeyNotFoundException ex) { // Wrap exception since only certain exception types are allowed throw new InvalidDataException(ex.Message, ex); } finally { Finish(); } }
private void Clean(IEnumerable <ManifestDigest> digestsToKeep) { var toDelete = ImplementationStore.ListAll().Except(digestsToKeep, ManifestDigestPartialEqualityComparer.Instance).ToList(); Handler.RunTask(ForEachTask.Create(Resources.RemovingOutdated, toDelete, x => ImplementationStore.Remove(x, Handler))); }
/// <summary> /// Signs a number of <see cref="Feed"/>s with a single <see cref="OpenPgpSecretKey"/>. /// </summary> /// <param name="secretKey">The private key to use for signing the files.</param> /// <param name="passphrase">The passphrase to use to unlock the key.</param> /// <exception cref="IOException">The feed file could not be read or written.</exception> /// <exception cref="UnauthorizedAccessException">Read or write access to the feed file is not permitted.</exception> private void SignFiles(OpenPgpSecretKey secretKey, string passphrase) { var task = new ForEachTask<FileInfo>("Signing feeds", _files, file => { SignedFeed signedFeed; try { signedFeed = SignedFeed.Load(file.FullName); } #region Error handling catch (UnauthorizedAccessException ex) { // Wrap exception since only certain exception types are allowed throw new IOException(ex.Message, ex); } catch (InvalidDataException ex) { // Wrap exception since only certain exception types are allowed throw new IOException(ex.Message + (ex.InnerException == null ? "" : "\n" + ex.InnerException.Message), ex); } #endregion signedFeed.SecretKey = secretKey; try { signedFeed.Save(file.FullName, passphrase); } #region Error handling catch (UnauthorizedAccessException ex) { // Wrap exception since only certain exception types are allowed throw new IOException(ex.Message, ex); } catch (KeyNotFoundException ex) { // Wrap exception since only certain exception types are allowed throw new IOException(ex.Message, ex); } catch (WrongPassphraseException ex) { // Wrap exception since only certain exception types are allowed throw new IOException(ex.Message, ex); } #endregion }); using (var handler = new GuiTaskHandler(this)) handler.RunTask(task); Msg.Inform(this, "Successfully signed files.", MsgSeverity.Info); }
/// <inheritdoc/> protected override void OnStage() { if (!Directory.Exists(DestinationPath)) { Directory.CreateDirectory(DestinationPath); _createdDirectories.Push(DestinationPath); } if (FileUtils.DetermineTimeAccuracy(DestinationPath) > 0) { throw new IOException(Resources.InsufficientFSTimeAccuracy); } string manifestPath = System.IO.Path.Combine(DestinationPath, Manifest.ManifestFile); string tempManifestPath = Randomize(manifestPath); _pendingFileRenames.Push(new KeyValuePair <string, string>(tempManifestPath, manifestPath)); Manifest.Save(tempManifestPath); Handler.RunTask(ForEachTask.Create(Resources.CopyFiles, ElementPaths, pair => { string sourcePath = System.IO.Path.Combine(Path, pair.Key); string destinationPath = System.IO.Path.Combine(DestinationPath, pair.Key); if (pair.Value is ManifestDirectory) { if (!Directory.Exists(destinationPath)) { Directory.CreateDirectory(destinationPath); _createdDirectories.Push(destinationPath); } } else { string tempPath = Randomize(destinationPath); _pendingFileRenames.Push(new KeyValuePair <string, string>(tempPath, destinationPath)); switch (pair.Value) { case ManifestFileBase file: File.Copy(sourcePath, tempPath); File.SetLastWriteTimeUtc(tempPath, file.ModifiedTime); if (UnixUtils.IsUnix) { FileUtils.SetExecutable(tempPath, file is ManifestExecutableFile); } break; case ManifestSymlink _: if (UnixUtils.IsUnix) { if (UnixUtils.IsSymlink(sourcePath, out string?symlinkTarget)) { UnixUtils.CreateSymlink(tempPath, symlinkTarget); } } break; } } })); }