Skip to content

Commit 6f92fbb

Browse files
committed
feat: add Install Monitor UI panel with Track This Installer flow
1 parent c18afb3 commit 6f92fbb

2 files changed

Lines changed: 96 additions & 1 deletion

File tree

src/DeepPurge.App/Views/MainWindow.xaml

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,13 @@
544544
</StackPanel>
545545
</RadioButton>
546546

547+
<RadioButton GroupName="nav" Tag="InstallMonitor" Checked="NavButton_Checked" Style="{StaticResource NavRadioButton}">
548+
<StackPanel Orientation="Horizontal">
549+
<TextBlock Text="&#xE8B5;" Style="{StaticResource NavIcon}"/>
550+
<TextBlock Text="Install Monitor" VerticalAlignment="Center"/>
551+
</StackPanel>
552+
</RadioButton>
553+
547554
<RadioButton GroupName="nav" Tag="History" Checked="NavButton_Checked" Style="{StaticResource NavRadioButton}">
548555
<StackPanel Orientation="Horizontal">
549556
<TextBlock Text="&#xE81C;" Style="{StaticResource NavIcon}"/>
@@ -1193,6 +1200,63 @@
11931200
Background="{DynamicResource MantleBrush}"/>
11941201
</Grid>
11951202

1203+
<!-- ═══════════════════════════════════════════════════════ -->
1204+
<!-- INSTALL MONITOR ("Track This Installer" flow) -->
1205+
<!-- ═══════════════════════════════════════════════════════ -->
1206+
<Border x:Name="panelInstallMonitor" Visibility="Collapsed"
1207+
AutomationProperties.Name="Install Monitor panel"
1208+
AutomationProperties.HelpText="Capture before and after snapshots of an installer to build an exact removal manifest.">
1209+
<Border Padding="60,48" MaxWidth="620" HorizontalAlignment="Left" VerticalAlignment="Top">
1210+
<StackPanel>
1211+
<Border Width="52" Height="52" CornerRadius="14" Margin="0,0,0,24" HorizontalAlignment="Left">
1212+
<Border.Background>
1213+
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
1214+
<GradientStop Color="{DynamicResource AccentColor}" Offset="0"/>
1215+
<GradientStop Color="{DynamicResource TealColor}" Offset="1"/>
1216+
</LinearGradientBrush>
1217+
</Border.Background>
1218+
<Border.Effect>
1219+
<DropShadowEffect Color="{DynamicResource AccentColor}" BlurRadius="18" ShadowDepth="0" Opacity="0.25"/>
1220+
</Border.Effect>
1221+
<TextBlock Text="&#xE8B5;" FontFamily="{StaticResource Ico}" FontSize="22" Foreground="#FFFFFF"
1222+
HorizontalAlignment="Center" VerticalAlignment="Center"/>
1223+
</Border>
1224+
<TextBlock Text="Track This Installer" FontSize="24" FontWeight="Bold" Margin="0,0,0,8"
1225+
Foreground="{DynamicResource TextBrush}"/>
1226+
<TextBlock TextWrapping="Wrap" Foreground="{DynamicResource SubtextBrush}"
1227+
Margin="0,0,0,32" FontSize="13" LineHeight="21">
1228+
Captures the full filesystem + registry state before and after an installer runs.
1229+
The resulting delta becomes a precise removal manifest for forced uninstall.
1230+
</TextBlock>
1231+
1232+
<TextBlock Text="PROGRAM NAME" FontSize="10" FontWeight="SemiBold"
1233+
Foreground="{DynamicResource Subtext0Brush}" Margin="2,0,0,8" Opacity="0.6"/>
1234+
<TextBox x:Name="txtMonitorName" Margin="0,0,0,22"
1235+
AutomationProperties.Name="Program name for install trace"/>
1236+
1237+
<TextBlock Text="INSTALLER PATH" FontSize="10" FontWeight="SemiBold"
1238+
Foreground="{DynamicResource Subtext0Brush}" Margin="2,0,0,8" Opacity="0.6"/>
1239+
<DockPanel Margin="0,0,0,22">
1240+
<Button DockPanel.Dock="Right" Content="Browse" Click="BrowseInstaller_Click" Margin="10,0,0,0" Padding="20,9"/>
1241+
<TextBox x:Name="txtMonitorInstaller"
1242+
AutomationProperties.Name="Path to installer executable"/>
1243+
</DockPanel>
1244+
1245+
<TextBlock Text="INSTALLER ARGUMENTS (optional)" FontSize="10" FontWeight="SemiBold"
1246+
Foreground="{DynamicResource Subtext0Brush}" Margin="2,0,0,8" Opacity="0.6"/>
1247+
<TextBox x:Name="txtMonitorArgs" Margin="0,0,0,32"
1248+
AutomationProperties.Name="Optional installer arguments"/>
1249+
1250+
<Button Content="Start Trace" Style="{DynamicResource AccentButton}"
1251+
Click="StartInstallTrace_Click" HorizontalAlignment="Left" Padding="32,11" FontSize="13"
1252+
AutomationProperties.Name="Begin install trace capture"/>
1253+
1254+
<TextBlock Text="{Binding SnapshotStatus}" TextWrapping="Wrap" Margin="0,24,0,0"
1255+
Foreground="{DynamicResource SubtextBrush}" FontSize="12.5"/>
1256+
</StackPanel>
1257+
</Border>
1258+
</Border>
1259+
11961260
<!-- ═══════════════════════════════════════════════════════ -->
11971261
<!-- ACTIVITY HISTORY -->
11981262
<!-- ═══════════════════════════════════════════════════════ -->

src/DeepPurge.App/Views/MainWindow.xaml.cs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ private void ShowToast(string message, bool isError = false, bool isWarning = fa
111111
panelHunter, panelBackups,
112112
// v0.9.0 system-tools panels
113113
dgDrivers, dgStartupImpact, dgShortcuts, dgDuplicates,
114-
panelWinapp2, panelRepair, panelSchedule, dgHistory, panelAbout,
114+
panelWinapp2, panelRepair, panelSchedule, panelInstallMonitor, dgHistory, panelAbout,
115115
};
116116

117117
private void NavButton_Checked(object sender, RoutedEventArgs e)
@@ -236,6 +236,9 @@ private void NavButton_Checked(object sender, RoutedEventArgs e)
236236
// Refresh every time — schedule list is cheap and can change externally.
237237
_vm.RefreshScheduledJobsCommand.Execute(null);
238238
break;
239+
case "InstallMonitor":
240+
panelInstallMonitor.Visibility = Visibility.Visible; txtPanelTitle.Text = "Install Monitor";
241+
break;
239242
case "History":
240243
dgHistory.Visibility = Visibility.Visible; txtPanelTitle.Text = "Activity History";
241244
_vm.LoadHistoryCommand.Execute(null);
@@ -902,6 +905,34 @@ private void BrowseFolder_Click(object sender, RoutedEventArgs e)
902905
if (dlg.ShowDialog() == true) txtForcedPath.Text = dlg.FolderName;
903906
}
904907

908+
private void BrowseInstaller_Click(object sender, RoutedEventArgs e)
909+
{
910+
var dlg = new Microsoft.Win32.OpenFileDialog
911+
{
912+
Title = "Select the installer executable",
913+
Filter = "Executables (*.exe;*.msi)|*.exe;*.msi|All files (*.*)|*.*",
914+
};
915+
if (dlg.ShowDialog() == true) txtMonitorInstaller.Text = dlg.FileName;
916+
}
917+
918+
private async void StartInstallTrace_Click(object sender, RoutedEventArgs e)
919+
{
920+
var name = txtMonitorName.Text.Trim();
921+
var installer = txtMonitorInstaller.Text.Trim();
922+
var args = txtMonitorArgs.Text.Trim();
923+
if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(installer))
924+
{
925+
_vm.StatusText = "Enter a program name and installer path first.";
926+
return;
927+
}
928+
_vm.StatusText = "Tracing installer — do not close DeepPurge...";
929+
var delta = await _vm.TraceInstallerAsync(name, installer, string.IsNullOrEmpty(args) ? null : args);
930+
if (delta != null)
931+
{
932+
DeepPurge.Core.Diagnostics.ActivityLog.Record("snapshot", $"{name}: +{delta.AddedFiles.Count} files, +{delta.AddedRegistryKeys.Count} keys", delta.TotalAddedBytes, delta.AddedFiles.Count);
933+
}
934+
}
935+
905936
protected override void OnClosing(CancelEventArgs e)
906937
{
907938
_vm.CancelOperation();

0 commit comments

Comments
 (0)