diff --git a/.gitignore b/.gitignore
index 23817a74..905236c7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -24,6 +24,7 @@ bld/
# Visual Studio 2015 cache/options directory
.vs/
+.vscode/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
diff --git a/installer/BcuSetup.iss b/installer/BcuSetup.iss
index d4374a16..cd9b07c1 100644
--- a/installer/BcuSetup.iss
+++ b/installer/BcuSetup.iss
@@ -140,6 +140,7 @@ Type: files; Name: "{app}\CleanLogs.bat"
Type: files; Name: "{app}\BCUninstaller.settings"
Type: files; Name: "{app}\*.log"
Type: files; Name: "{app}\Exception_*.zip"
+Type: files; Name: "{app}\CustomNotes.xml"
Type: files; Name: "{app}\InfoCache.xml"
Type: files; Name: "{app}\CertCache.xml"
Type: files; Name: "{app}\UsageStatistics.xml"
@@ -148,6 +149,7 @@ Type: files; Name: "{app}\*\CleanLogs.bat"
Type: files; Name: "{app}\*\BCUninstaller.settings"
Type: files; Name: "{app}\*\*.log"
Type: files; Name: "{app}\*\Exception_*.zip"
+Type: files; Name: "{app}\*\CustomNotes.xml"
Type: files; Name: "{app}\*\InfoCache.xml"
Type: files; Name: "{app}\*\CertCache.xml"
Type: files; Name: "{app}\*\UsageStatistics.xml"
diff --git a/source/BulkCrapUninstaller/Forms/Helpers/CustomNoteDialog.Designer.cs b/source/BulkCrapUninstaller/Forms/Helpers/CustomNoteDialog.Designer.cs
new file mode 100644
index 00000000..88077545
--- /dev/null
+++ b/source/BulkCrapUninstaller/Forms/Helpers/CustomNoteDialog.Designer.cs
@@ -0,0 +1,90 @@
+namespace BulkCrapUninstaller.Forms
+{
+ partial class CustomNoteDialog
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(CustomNoteDialog));
+ this.txtNote = new System.Windows.Forms.TextBox();
+ this.btnOk = new System.Windows.Forms.Button();
+ this.btnCancel = new System.Windows.Forms.Button();
+ this.SuspendLayout();
+
+ // txtNote
+ this.txtNote.AcceptsReturn = true;
+ this.txtNote.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.txtNote.Location = new System.Drawing.Point(12, 12);
+ this.txtNote.Multiline = true;
+ this.txtNote.Name = "txtNote";
+ this.txtNote.Size = new System.Drawing.Size(360, 150);
+ this.txtNote.TabIndex = 0;
+
+ // btnOk
+ this.btnOk.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+ this.btnOk.DialogResult = System.Windows.Forms.DialogResult.OK;
+ this.btnOk.Location = new System.Drawing.Point(216, 175);
+ this.btnOk.Name = "btnOk";
+ this.btnOk.Size = new System.Drawing.Size(75, 23);
+ this.btnOk.TabIndex = 1;
+ resources.ApplyResources(this.btnOk, "btnOk");
+ this.btnOk.UseVisualStyleBackColor = true;
+
+ // btnCancel
+ this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+ this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+ this.btnCancel.Location = new System.Drawing.Point(297, 175);
+ this.btnCancel.Name = "btnCancel";
+ this.btnCancel.Size = new System.Drawing.Size(75, 23);
+ this.btnCancel.TabIndex = 2;
+ resources.ApplyResources(this.btnCancel, "btnCancel");
+ this.btnCancel.UseVisualStyleBackColor = true;
+
+ // CustomNoteDialog
+ this.AcceptButton = this.btnOk;
+ this.CancelButton = this.btnCancel;
+ this.ClientSize = new System.Drawing.Size(384, 211);
+ this.Controls.Add(this.btnCancel);
+ this.Controls.Add(this.btnOk);
+ this.Controls.Add(this.txtNote);
+ this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Sizable;
+ this.Name = "CustomNoteDialog";
+ this.ShowIcon = false;
+ this.ShowInTaskbar = false;
+ resources.ApplyResources(this, "$this");
+ this.ResumeLayout(false);
+ this.PerformLayout();
+ }
+
+ #endregion
+
+ private System.Windows.Forms.TextBox txtNote;
+ private System.Windows.Forms.Button btnOk;
+ private System.Windows.Forms.Button btnCancel;
+ }
+}
diff --git a/source/BulkCrapUninstaller/Forms/Helpers/CustomNoteDialog.cs b/source/BulkCrapUninstaller/Forms/Helpers/CustomNoteDialog.cs
new file mode 100644
index 00000000..172253c3
--- /dev/null
+++ b/source/BulkCrapUninstaller/Forms/Helpers/CustomNoteDialog.cs
@@ -0,0 +1,26 @@
+using System.Windows.Forms;
+
+namespace BulkCrapUninstaller.Forms
+{
+ public partial class CustomNoteDialog : Form
+ {
+ public string NoteText
+ {
+ get => txtNote.Text;
+ set => txtNote.Text = value;
+ }
+
+ public CustomNoteDialog(string appName, string existingNote) : this()
+ {
+ // Append the app name to the localized base title
+ this.Text = this.Text + appName;
+ this.NoteText = existingNote;
+ this.StartPosition = FormStartPosition.CenterParent;
+ }
+
+ private CustomNoteDialog()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/source/BulkCrapUninstaller/Forms/Helpers/CustomNoteDialog.resx b/source/BulkCrapUninstaller/Forms/Helpers/CustomNoteDialog.resx
new file mode 100644
index 00000000..e2121984
--- /dev/null
+++ b/source/BulkCrapUninstaller/Forms/Helpers/CustomNoteDialog.resx
@@ -0,0 +1,70 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ OK
+
+
+ Cancel
+
+
+ Custom Note for
+
+
\ No newline at end of file
diff --git a/source/BulkCrapUninstaller/Forms/Windows/MainWindow.Designer.cs b/source/BulkCrapUninstaller/Forms/Windows/MainWindow.Designer.cs
index e5303b8a..35b2b23c 100644
--- a/source/BulkCrapUninstaller/Forms/Windows/MainWindow.Designer.cs
+++ b/source/BulkCrapUninstaller/Forms/Windows/MainWindow.Designer.cs
@@ -1,4 +1,4 @@
-using System.ComponentModel;
+using System.ComponentModel;
using System.Windows.Forms;
using BrightIdeasSoftware;
using BulkCrapUninstaller.Controls;
@@ -48,6 +48,7 @@ private void InitializeComponent()
olvColumnRegistryKeyName = new OLVColumn();
olvColumnGuid = new OLVColumn();
olvColumnQuietUninstallString = new OLVColumn();
+ olvColumnCustomNote = new OLVColumn();
treeMap1 = new SimpleTreeMap.TreeMap();
toolStrip = new ToolStrip();
toolStripButton1 = new ToolStripButton();
@@ -149,12 +150,12 @@ private void InitializeComponent()
automaticallyStartedToolStripMenuItem = new ToolStripMenuItem();
onlyWebBrowsersToolStripMenuItem = new ToolStripMenuItem();
toolStripSeparator31 = new ToolStripSeparator();
- viewTweaksToolStripMenuItem = new ToolStripMenuItem();
- viewUnregisteredToolStripMenuItem = new ToolStripMenuItem();
- viewUpdatesToolStripMenuItem = new ToolStripMenuItem();
- viewInvalidToolStripMenuItem = new ToolStripMenuItem();
- viewWindowsFeaturesToolStripMenuItem = new ToolStripMenuItem();
- viewWindowsStoreAppsToolStripMenuItem = new ToolStripMenuItem();
+ viewTweaksToolStripMenuItem = new ToolStripMenuItem();
+ viewUnregisteredToolStripMenuItem = new ToolStripMenuItem();
+ viewUpdatesToolStripMenuItem = new ToolStripMenuItem();
+ viewInvalidToolStripMenuItem = new ToolStripMenuItem();
+ viewWindowsFeaturesToolStripMenuItem = new ToolStripMenuItem();
+ viewWindowsStoreAppsToolStripMenuItem = new ToolStripMenuItem();
toolStripSeparator28 = new ToolStripSeparator();
searchToolStripMenuItem = new ToolStripMenuItem();
basicOperationsToolStripMenuItem = new ToolStripMenuItem();
@@ -234,6 +235,7 @@ private void InitializeComponent()
globalHotkeys1 = new Klocman.Subsystems.GlobalHotkeys();
splashScreen1 = new Klocman.Forms.SplashScreen();
usageTracker = new UsageTracker();
+ editCustomNoteMenuItem = new ToolStripMenuItem();
((ISupportInitialize)splitContainer1).BeginInit();
splitContainer1.Panel1.SuspendLayout();
splitContainer1.Panel2.SuspendLayout();
@@ -298,6 +300,7 @@ private void InitializeComponent()
// uninstallerObjectListView
//
uninstallerObjectListView.AllColumns.Add(olvColumnDisplayName);
+ uninstallerObjectListView.AllColumns.Add(olvColumnCustomNote);
uninstallerObjectListView.AllColumns.Add(olvColumnPublisher);
uninstallerObjectListView.AllColumns.Add(olvColumnCertificate);
uninstallerObjectListView.AllColumns.Add(olvColumnRating);
@@ -322,7 +325,7 @@ private void InitializeComponent()
uninstallerObjectListView.CellEditActivation = ObjectListView.CellEditActivateMode.DoubleClick;
uninstallerObjectListView.CellEditUseWholeCell = false;
uninstallerObjectListView.CheckBoxes = true;
- uninstallerObjectListView.Columns.AddRange(new ColumnHeader[] { olvColumnDisplayName, olvColumnPublisher, olvColumnCertificate, olvColumnRating, olvColumnDisplayVersion, olvColumnInstallDate, olvColumnSize, olvColumnStartup, olvColumnIs64, olvColumnUninstallString, olvColumnAbout, olvColumnInstallSource, olvColumnInstallLocation, olvColumnUninstallerKind, olvColumnSystemComponent, olvColumnProtected, olvColumnIntegrity, olvColumnRegistryKeyName, olvColumnGuid, olvColumnQuietUninstallString });
+ uninstallerObjectListView.Columns.AddRange(new ColumnHeader[] { olvColumnDisplayName, olvColumnCustomNote, olvColumnPublisher, olvColumnCertificate, olvColumnRating, olvColumnDisplayVersion, olvColumnInstallDate, olvColumnSize, olvColumnStartup, olvColumnIs64, olvColumnUninstallString, olvColumnAbout, olvColumnInstallSource, olvColumnInstallLocation, olvColumnUninstallerKind, olvColumnSystemComponent, olvColumnProtected, olvColumnIntegrity, olvColumnRegistryKeyName, olvColumnGuid, olvColumnQuietUninstallString });
resources.ApplyResources(uninstallerObjectListView, "uninstallerObjectListView");
uninstallerObjectListView.FullRowSelect = true;
uninstallerObjectListView.GridLines = true;
@@ -438,6 +441,12 @@ private void InitializeComponent()
//
resources.ApplyResources(olvColumnQuietUninstallString, "olvColumnQuietUninstallString");
//
+ // olvColumnCustomNote
+ //
+ olvColumnCustomNote.AspectName = "CustomNote";
+ olvColumnCustomNote.Text = "Custom Note";
+ olvColumnCustomNote.Width = 150;
+ //
// treeMap1
//
resources.ApplyResources(treeMap1, "treeMap1");
@@ -629,7 +638,7 @@ private void InitializeComponent()
// uninstallListContextMenuStrip
//
uninstallListContextMenuStrip.ImageScalingSize = new System.Drawing.Size(20, 20);
- uninstallListContextMenuStrip.Items.AddRange(new ToolStripItem[] { uninstallContextMenuStripItem, quietUninstallContextMenuStripItem, manualUninstallToolStripMenuItem1, uninstallUsingMsiExecContextMenuStripItem, toolStripSeparator3, excludeToolStripMenuItem, includeToolStripMenuItem, toolStripSeparatorFiltering, runToolStripMenuItem, toolStripSeparator8, copyToClipboardContextMenuStripItem, deleteRegistryEntryContextMenuStripItem, renameContextMenuStripItem, toolStripSeparator6, openInExplorerContextMenuStripItem, openWebPageContextMenuStripItem, lookUpOnlineToolStripMenuItem, rateToolStripMenuItem, toolStripSeparator7, propertiesContextMenuStripItem });
+ uninstallListContextMenuStrip.Items.AddRange(new ToolStripItem[] { uninstallContextMenuStripItem, quietUninstallContextMenuStripItem, manualUninstallToolStripMenuItem1, uninstallUsingMsiExecContextMenuStripItem, toolStripSeparator3, excludeToolStripMenuItem, includeToolStripMenuItem, toolStripSeparatorFiltering, runToolStripMenuItem, toolStripSeparator8, copyToClipboardContextMenuStripItem, deleteRegistryEntryContextMenuStripItem, renameContextMenuStripItem, toolStripSeparator6, openInExplorerContextMenuStripItem, openWebPageContextMenuStripItem, lookUpOnlineToolStripMenuItem, rateToolStripMenuItem, toolStripSeparator7, editCustomNoteMenuItem, propertiesContextMenuStripItem });
uninstallListContextMenuStrip.Name = "uninstallListContextMenuStrip";
resources.ApplyResources(uninstallListContextMenuStrip, "uninstallListContextMenuStrip");
uninstallListContextMenuStrip.Opening += UpdateUninstallListContextMenuStrip;
@@ -768,6 +777,12 @@ private void InitializeComponent()
resources.ApplyResources(renameContextMenuStripItem, "renameContextMenuStripItem");
renameContextMenuStripItem.Click += RenameEntries;
//
+ // editCustomNoteMenuItem
+ //
+ editCustomNoteMenuItem.Name = "editCustomNoteMenuItem";
+ editCustomNoteMenuItem.Text = "Edit note...";
+ editCustomNoteMenuItem.Click += editCustomNoteMenuItem_Click;
+ //
// toolStripSeparator6
//
toolStripSeparator6.Name = "toolStripSeparator6";
@@ -1011,7 +1026,7 @@ private void InitializeComponent()
//
// filteringToolStripMenuItem
//
- filteringToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { advancedApplicationsToolStripMenuItem, basicApplicationsToolStripMenuItem, systemComponentsToolStripMenuItem, everythingToolStripMenuItem, toolStripSeparator20, automaticallyStartedToolStripMenuItem, onlyWebBrowsersToolStripMenuItem, toolStripSeparator31, viewTweaksToolStripMenuItem, viewUnregisteredToolStripMenuItem, viewUpdatesToolStripMenuItem, viewInvalidToolStripMenuItem, viewWindowsFeaturesToolStripMenuItem, viewWindowsStoreAppsToolStripMenuItem, toolStripSeparator28, searchToolStripMenuItem });
+ filteringToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { advancedApplicationsToolStripMenuItem, basicApplicationsToolStripMenuItem, systemComponentsToolStripMenuItem, everythingToolStripMenuItem, toolStripSeparator20, automaticallyStartedToolStripMenuItem, onlyWebBrowsersToolStripMenuItem, toolStripSeparator31, viewTweaksToolStripMenuItem, viewUnregisteredToolStripMenuItem, viewUpdatesToolStripMenuItem, viewInvalidToolStripMenuItem, viewWindowsFeaturesToolStripMenuItem, viewWindowsStoreAppsToolStripMenuItem, toolStripSeparator28, searchToolStripMenuItem });
filteringToolStripMenuItem.Name = "filteringToolStripMenuItem";
resources.ApplyResources(filteringToolStripMenuItem, "filteringToolStripMenuItem");
filteringToolStripMenuItem.DropDownOpening += filteringToolStripMenuItem_DropDownOpening;
@@ -1075,22 +1090,22 @@ private void InitializeComponent()
viewUnregisteredToolStripMenuItem.Name = "viewUnregisteredToolStripMenuItem";
resources.ApplyResources(viewUnregisteredToolStripMenuItem, "viewUnregisteredToolStripMenuItem");
viewUnregisteredToolStripMenuItem.Click += viewUnregisteredToolStripMenuItem_Click;
- //
- // viewUpdatesToolStripMenuItem
- //
- viewUpdatesToolStripMenuItem.Name = "viewUpdatesToolStripMenuItem";
- resources.ApplyResources(viewUpdatesToolStripMenuItem, "viewUpdatesToolStripMenuItem");
- viewUpdatesToolStripMenuItem.Click += viewUpdatesToolStripMenuItem_Click;
- //
- // viewInvalidToolStripMenuItem
- //
- viewInvalidToolStripMenuItem.Name = "viewInvalidToolStripMenuItem";
- resources.ApplyResources(viewInvalidToolStripMenuItem, "viewInvalidToolStripMenuItem");
- viewInvalidToolStripMenuItem.Click += viewInvalidToolStripMenuItem_Click;
- //
- // viewWindowsFeaturesToolStripMenuItem
- //
- viewWindowsFeaturesToolStripMenuItem.Name = "viewWindowsFeaturesToolStripMenuItem";
+ //
+ // viewUpdatesToolStripMenuItem
+ //
+ viewUpdatesToolStripMenuItem.Name = "viewUpdatesToolStripMenuItem";
+ resources.ApplyResources(viewUpdatesToolStripMenuItem, "viewUpdatesToolStripMenuItem");
+ viewUpdatesToolStripMenuItem.Click += viewUpdatesToolStripMenuItem_Click;
+ //
+ // viewInvalidToolStripMenuItem
+ //
+ viewInvalidToolStripMenuItem.Name = "viewInvalidToolStripMenuItem";
+ resources.ApplyResources(viewInvalidToolStripMenuItem, "viewInvalidToolStripMenuItem");
+ viewInvalidToolStripMenuItem.Click += viewInvalidToolStripMenuItem_Click;
+ //
+ // viewWindowsFeaturesToolStripMenuItem
+ //
+ viewWindowsFeaturesToolStripMenuItem.Name = "viewWindowsFeaturesToolStripMenuItem";
resources.ApplyResources(viewWindowsFeaturesToolStripMenuItem, "viewWindowsFeaturesToolStripMenuItem");
viewWindowsFeaturesToolStripMenuItem.Click += viewWindowsFeaturesToolStripMenuItem_Click;
//
@@ -1618,15 +1633,16 @@ private void InitializeComponent()
internal OLVColumn olvColumnGuid;
internal OLVColumn olvColumnSize;
internal OLVColumn olvColumnInstallSource;
- internal OLVColumn olvColumnInstallLocation;
- internal OLVColumn olvColumnUninstallerKind;
- internal OLVColumn olvColumnAbout;
- internal OLVColumn olvColumnRegistryKeyName;
- internal OLVColumn olvColumnCertificate;
- internal OLVColumn olvColumnSystemComponent;
- internal OLVColumn olvColumnIntegrity;
- internal OLVColumn olvColumnQuietUninstallString;
- internal OLVColumn olvColumnProtected;
+ internal OLVColumn olvColumnInstallLocation;
+ internal OLVColumn olvColumnUninstallerKind;
+ internal OLVColumn olvColumnAbout;
+ internal OLVColumn olvColumnRegistryKeyName;
+ internal OLVColumn olvColumnCertificate;
+ internal OLVColumn olvColumnSystemComponent;
+ internal OLVColumn olvColumnIntegrity;
+ internal OLVColumn olvColumnQuietUninstallString;
+ internal OLVColumn olvColumnProtected;
+ internal OLVColumn olvColumnCustomNote;
private SaveFileDialog exportDialog;
private ContextMenuStrip uninstallListContextMenuStrip;
private ToolStripMenuItem uninstallContextMenuStripItem;
@@ -1767,13 +1783,13 @@ private void InitializeComponent()
private ToolStripMenuItem alternativeToToolStripMenuItem;
private ToolStripMenuItem toolStripMenuItem15;
private ToolStripMenuItem toolStripMenuItem16;
- private ToolStripMenuItem openSystemRestoreToolStripMenuItem;
- private Klocman.Forms.SplashScreen splashScreen1;
- private ToolStripSeparator toolStripSeparator3;
- private ToolStripMenuItem runToolStripMenuItem;
- private ToolStripMenuItem viewUpdatesToolStripMenuItem;
- private ToolStripMenuItem viewInvalidToolStripMenuItem;
- private ToolStripMenuItem targetMenuItem;
+ private ToolStripMenuItem openSystemRestoreToolStripMenuItem;
+ private Klocman.Forms.SplashScreen splashScreen1;
+ private ToolStripSeparator toolStripSeparator3;
+ private ToolStripMenuItem runToolStripMenuItem;
+ private ToolStripMenuItem viewUpdatesToolStripMenuItem;
+ private ToolStripMenuItem viewInvalidToolStripMenuItem;
+ private ToolStripMenuItem targetMenuItem;
private ToolStripSeparator toolStripSeparator25;
private ToolStripSeparator toolStripSeparator26;
private ToolStripMenuItem fossHubcomToolStripMenuItem;
@@ -1818,6 +1834,6 @@ private void InitializeComponent()
private ToolStripMenuItem createRestorePointToolStripMenuItem;
private ToolStripSeparator toolStripSeparator33;
private ToolStripMenuItem autosizeAllColumnsToolStripMenuItem;
+ private ToolStripMenuItem editCustomNoteMenuItem;
}
}
-
diff --git a/source/BulkCrapUninstaller/Forms/Windows/MainWindow.cs b/source/BulkCrapUninstaller/Forms/Windows/MainWindow.cs
index 3d80d2e0..c85c0c60 100644
--- a/source/BulkCrapUninstaller/Forms/Windows/MainWindow.cs
+++ b/source/BulkCrapUninstaller/Forms/Windows/MainWindow.cs
@@ -1904,5 +1904,42 @@ private void autosizeAllColumnsToolStripMenuItem_Click(object sender, EventArgs
{
uninstallerObjectListView.AutoResizeColumns();
}
+
+ private void editCustomNoteMenuItem_Click(object sender, EventArgs e)
+ {
+ var selectedUninstallers = _listView.SelectedUninstallers.ToList();
+ if (selectedUninstallers.Count == 0) return;
+
+ string title;
+ string existingNote = string.Empty;
+
+ if (selectedUninstallers.Count == 1)
+ {
+ var entry = selectedUninstallers[0];
+ title = entry.DisplayName;
+ existingNote = entry.CustomNote;
+ }
+ else
+ {
+ title = $"{selectedUninstallers.Count} items";
+ var firstNote = selectedUninstallers[0].CustomNote ?? string.Empty;
+ if (selectedUninstallers.All(x => (x.CustomNote ?? string.Empty) == firstNote))
+ {
+ existingNote = firstNote;
+ }
+ }
+
+ using (var dialog = new BulkCrapUninstaller.Forms.CustomNoteDialog(title, existingNote))
+ {
+ if (dialog.ShowDialog(this) == DialogResult.OK)
+ {
+ foreach (var entry in selectedUninstallers)
+ {
+ entry.CustomNote = dialog.NoteText;
+ }
+ this.uninstallerObjectListView.RefreshObjects(selectedUninstallers);
+ }
+ }
+ }
}
}
diff --git a/source/UninstallTools/ApplicationUninstallerEntry.cs b/source/UninstallTools/ApplicationUninstallerEntry.cs
index b5130184..4e1fb43a 100644
--- a/source/UninstallTools/ApplicationUninstallerEntry.cs
+++ b/source/UninstallTools/ApplicationUninstallerEntry.cs
@@ -117,6 +117,14 @@ public string DisplayName
[LocalisedName(typeof(Localisation), nameof(Localisation.Comment))]
public string Comment { get; set; }
+ [XmlIgnore]
+ [LocalisedName(typeof(Localisation), nameof(Localisation.CustomNote))]
+ public string CustomNote
+ {
+ get => CustomNotesManager.GetNote(GetCacheId());
+ set => CustomNotesManager.SetNote(GetCacheId(), value);
+ }
+
[LocalisedName(typeof(Localisation), nameof(Localisation.DisplayIcon))]
public string DisplayIcon
{
@@ -177,20 +185,20 @@ public string InstallSource
///
/// True if this is an update for another product
///
- [ComparisonTarget]
- [LocalisedName(typeof(Localisation), nameof(Localisation.IsUpdate))]
- public bool IsUpdate { get; set; }
-
- [XmlIgnore]
- [ComparisonTarget]
- public bool IsScriptTweak => !string.IsNullOrEmpty(RatingId) &&
- RatingId.StartsWith("Tweak-", StringComparison.OrdinalIgnoreCase);
-
- ///
- /// True if the application can be uninstalled. False if the uninstaller is missing or is otherwise invalid.
- ///
- [ComparisonTarget]
- [LocalisedName(typeof(Localisation), nameof(Localisation.IsValid))]
+ [ComparisonTarget]
+ [LocalisedName(typeof(Localisation), nameof(Localisation.IsUpdate))]
+ public bool IsUpdate { get; set; }
+
+ [XmlIgnore]
+ [ComparisonTarget]
+ public bool IsScriptTweak => !string.IsNullOrEmpty(RatingId) &&
+ RatingId.StartsWith("Tweak-", StringComparison.OrdinalIgnoreCase);
+
+ ///
+ /// True if the application can be uninstalled. False if the uninstaller is missing or is otherwise invalid.
+ ///
+ [ComparisonTarget]
+ [LocalisedName(typeof(Localisation), nameof(Localisation.IsValid))]
public bool IsValid { get; set; }
///
@@ -528,4 +536,4 @@ private static string CleanupPath(string path, bool isFilename = false)
return path.TrimEnd('\\');
}
}
-}
+}
diff --git a/source/UninstallTools/CustomNotesManager.cs b/source/UninstallTools/CustomNotesManager.cs
new file mode 100644
index 00000000..5193185a
--- /dev/null
+++ b/source/UninstallTools/CustomNotesManager.cs
@@ -0,0 +1,73 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using Klocman.Tools;
+
+namespace UninstallTools
+{
+ public static class CustomNotesManager
+ {
+ private static readonly string NotesFilePath = Path.Combine(UninstallToolsGlobalConfig.AssemblyLocation, "CustomNotes.xml");
+ private static Dictionary _notesCache = new Dictionary();
+
+ static CustomNotesManager()
+ {
+ if (File.Exists(NotesFilePath))
+ {
+ try
+ {
+ var loaded = SerializationTools.DeserializeFromXml>(NotesFilePath);
+ if (loaded != null)
+ {
+ _notesCache = loaded
+ .Where(x => !string.IsNullOrEmpty(x.CacheId) && !string.IsNullOrEmpty(x.Note))
+ .ToDictionary(x => x.CacheId, x => x.Note);
+ }
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine("Failed to load CustomNotes.xml: " + ex.Message);
+ }
+ }
+ }
+
+ public static string GetNote(string cacheId)
+ {
+ if (string.IsNullOrEmpty(cacheId)) return string.Empty;
+ return _notesCache.TryGetValue(cacheId, out var note) ? note : string.Empty;
+ }
+
+ public static void SetNote(string cacheId, string note)
+ {
+ if (string.IsNullOrEmpty(cacheId)) return;
+
+ if (string.IsNullOrEmpty(note))
+ _notesCache.Remove(cacheId);
+ else
+ _notesCache[cacheId] = note;
+
+ Save();
+ }
+
+ private static void Save()
+ {
+ try
+ {
+ var listToSave = _notesCache.Select(kv => new NoteEntry { CacheId = kv.Key, Note = kv.Value }).ToList();
+ SerializationTools.SerializeToXml(NotesFilePath, listToSave);
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine("Failed to save CustomNotes.xml: " + ex.Message);
+ }
+ }
+
+ public class NoteEntry
+ {
+ public string CacheId { get; set; }
+ public string Note { get; set; }
+ }
+ }
+}
diff --git a/source/UninstallTools/Properties/Localisation.Designer.cs b/source/UninstallTools/Properties/Localisation.Designer.cs
index bc0cc369..eee9b68e 100644
--- a/source/UninstallTools/Properties/Localisation.Designer.cs
+++ b/source/UninstallTools/Properties/Localisation.Designer.cs
@@ -1445,5 +1445,14 @@ internal static string UninstallString {
return ResourceManager.GetString("UninstallString", resourceCulture);
}
}
+
+ ///
+ /// Looks up a localized string similar to Custom Note.
+ ///
+ internal static string CustomNote {
+ get {
+ return ResourceManager.GetString("CustomNote", resourceCulture);
+ }
+ }
}
}
diff --git a/source/UninstallTools/Properties/Localisation.resx b/source/UninstallTools/Properties/Localisation.resx
index b00681ec..602955da 100644
--- a/source/UninstallTools/Properties/Localisation.resx
+++ b/source/UninstallTools/Properties/Localisation.resx
@@ -587,4 +587,7 @@
Located directly inside a Known Folder
+
+ Custom Note
+
\ No newline at end of file