Skip to content

Commit 2e6dcb8

Browse files
committed
Add Windows Startup Programs management feature (MINOR)
Implements v1.1 feature: Windows Startup Programs management as a separate tab New Features: - Separate "Startup Programs" tab alongside "Context Menus" tab - Discover startup items from Run and RunOnce registry keys (User and System) - Enable/disable startup items using Windows 10+ StartupApproved mechanism - Delete startup entries with confirmation dialog - Backup startup items to .REG file - Publisher detection from common path patterns - Windows system program filtering Architecture: - Models/StartupItem.cs: Data model with StartupLocation enum - Services/IStartupService.cs & StartupService.cs: Registry operations - ViewModels/StartupViewModel.cs: MVVM pattern following MainViewModel - Views/StartupView.xaml: UserControl with DataGrid and action buttons - Reuses existing infrastructure (ViewModelBase, RelayCommand, theming) UI Changes: - MainWindow.xaml: Converted to TabControl with two tabs - App.xaml: Added TabControl and TabItem styling - Consistent layout: DataGrid + action buttons + status bar Technical Details: - Registry paths: HKCU/HKLM CurrentVersion\Run and RunOnce - Disable tracking: StartupApproved\Run registry keys - Same async patterns and error handling as context menu feature - Requires admin rights for system-level startup items Testing: - Build successful - Requires elevated privileges to run - Ready for runtime testing Documentation: - Updated PRD.md with v1.1 development notes - Documented registry locations and implementation approach
1 parent a635591 commit 2e6dcb8

9 files changed

Lines changed: 1095 additions & 74 deletions

File tree

App.xaml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,49 @@
136136
<Style TargetType="TextBlock">
137137
<Setter Property="Foreground" Value="{DynamicResource TextForegroundBrush}"/>
138138
</Style>
139+
140+
<Style TargetType="TabControl">
141+
<Setter Property="Background" Value="{DynamicResource WindowBackgroundBrush}"/>
142+
<Setter Property="BorderBrush" Value="{DynamicResource BorderBrush}"/>
143+
<Setter Property="BorderThickness" Value="1"/>
144+
</Style>
145+
146+
<Style TargetType="TabItem">
147+
<Setter Property="Background" Value="{DynamicResource ControlBackgroundBrush}"/>
148+
<Setter Property="Foreground" Value="{DynamicResource TextForegroundBrush}"/>
149+
<Setter Property="BorderBrush" Value="{DynamicResource BorderBrush}"/>
150+
<Setter Property="Padding" Value="12,6"/>
151+
<Setter Property="Margin" Value="0,0,2,0"/>
152+
<Setter Property="Template">
153+
<Setter.Value>
154+
<ControlTemplate TargetType="TabItem">
155+
<Border Name="Border"
156+
Background="{TemplateBinding Background}"
157+
BorderBrush="{TemplateBinding BorderBrush}"
158+
BorderThickness="1,1,1,0"
159+
CornerRadius="3,3,0,0"
160+
Padding="{TemplateBinding Padding}">
161+
<ContentPresenter x:Name="ContentSite"
162+
VerticalAlignment="Center"
163+
HorizontalAlignment="Center"
164+
ContentSource="Header"
165+
TextBlock.Foreground="{TemplateBinding Foreground}"/>
166+
</Border>
167+
<ControlTemplate.Triggers>
168+
<Trigger Property="IsSelected" Value="True">
169+
<Setter Property="Panel.ZIndex" Value="100"/>
170+
<Setter TargetName="Border" Property="Background" Value="{DynamicResource WindowBackgroundBrush}"/>
171+
<Setter TargetName="Border" Property="BorderThickness" Value="1,1,1,0"/>
172+
<Setter Property="FontWeight" Value="SemiBold"/>
173+
</Trigger>
174+
<Trigger Property="IsMouseOver" Value="True">
175+
<Setter TargetName="Border" Property="Background" Value="{DynamicResource ButtonHoverBrush}"/>
176+
</Trigger>
177+
</ControlTemplate.Triggers>
178+
</ControlTemplate>
179+
</Setter.Value>
180+
</Setter>
181+
</Style>
139182
</ResourceDictionary>
140183
</Application.Resources>
141184
</Application>

Models/StartupItem.cs

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
using System.ComponentModel;
2+
using System.Runtime.CompilerServices;
3+
4+
namespace ContextMenuEditor.Models;
5+
6+
/// <summary>
7+
/// Represents a Windows startup entry that runs when Windows starts.
8+
/// Follows the Single Responsibility Principle - only contains data, no business logic.
9+
/// </summary>
10+
public class StartupItem : INotifyPropertyChanged
11+
{
12+
private bool _isEnabled;
13+
14+
/// <summary>
15+
/// Gets or sets whether this startup item is currently enabled.
16+
/// </summary>
17+
public bool IsEnabled
18+
{
19+
get => _isEnabled;
20+
set
21+
{
22+
if (_isEnabled != value)
23+
{
24+
_isEnabled = value;
25+
OnPropertyChanged();
26+
}
27+
}
28+
}
29+
30+
/// <summary>
31+
/// Gets or sets the registry value name for this startup item.
32+
/// </summary>
33+
public string Name { get; set; } = string.Empty;
34+
35+
/// <summary>
36+
/// Gets or sets the command/path that executes when Windows starts.
37+
/// </summary>
38+
public string Command { get; set; } = string.Empty;
39+
40+
/// <summary>
41+
/// Gets or sets the publisher/vendor of the software.
42+
/// </summary>
43+
public string? Publisher { get; set; }
44+
45+
/// <summary>
46+
/// Gets or sets the location type (User Run, System Run, User RunOnce, System RunOnce).
47+
/// </summary>
48+
public StartupLocation Location { get; set; }
49+
50+
/// <summary>
51+
/// Gets or sets the full registry path for this startup item.
52+
/// </summary>
53+
public string RegistryPath { get; set; } = string.Empty;
54+
55+
/// <summary>
56+
/// Gets or sets whether this is a system-level (as opposed to user-level) entry.
57+
/// </summary>
58+
public bool IsSystemLevel { get; set; }
59+
60+
#region INotifyPropertyChanged
61+
62+
public event PropertyChangedEventHandler? PropertyChanged;
63+
64+
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
65+
{
66+
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
67+
}
68+
69+
#endregion
70+
}
71+
72+
/// <summary>
73+
/// Defines the registry locations where startup items can be found.
74+
/// </summary>
75+
public enum StartupLocation
76+
{
77+
/// <summary>
78+
/// HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run
79+
/// </summary>
80+
UserRun,
81+
82+
/// <summary>
83+
/// HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run
84+
/// </summary>
85+
SystemRun,
86+
87+
/// <summary>
88+
/// HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce
89+
/// </summary>
90+
UserRunOnce,
91+
92+
/// <summary>
93+
/// HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnce
94+
/// </summary>
95+
SystemRunOnce
96+
}

PRD.md

Lines changed: 75 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
# Context Menu Editor - Product Requirements Document
22

33
## Overview
4-
Context Menu Editor is a Windows GUI application that allows users to easily manage, edit, and customize context menu items for files, directories, and drives through an intuitive interface.
4+
Context Menu Editor is a Windows GUI application that allows users to easily manage, edit, and customize context menu items and startup programs through an intuitive interface.
55

6-
**Status**: ✅ **v1.0 COMPLETED** - See Implementation Summary section below
6+
**Status**: 🚧 **v1.1 IN DEVELOPMENT** - Adding Windows Startup Management
7+
**v1.0**: ✅ COMPLETED - See Implementation Summary section below
78

89
## Product Vision
9-
To provide Windows users with a simple, safe, and comprehensive tool for customizing their right-click context menus without requiring direct registry editing knowledge.
10+
To provide Windows users with a simple, safe, and comprehensive tool for managing their Windows customizations (context menus and startup programs) without requiring direct registry editing knowledge.
1011

1112
## Target Audience
1213
- **Primary**: Power users and system administrators who want to customize their Windows experience
@@ -59,6 +60,23 @@ To provide Windows users with a simple, safe, and comprehensive tool for customi
5960
- Keyboard shortcuts
6061
- Custom context menu creation and editing
6162

63+
### 5. Windows Startup Management 🚧 **IN DEVELOPMENT (v1.1)**
64+
- 🚧 **Separate Tab Interface**: Dedicated "Startup Programs" tab alongside "Context Menus" tab
65+
- 🚧 **Startup Discovery**: Discovers startup items from:
66+
- `HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run`
67+
- `HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run`
68+
- `HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce`
69+
- `HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnce`
70+
- 🚧 **Enable/Disable Startup Items**:
71+
- Uses Windows 10+ `StartupApproved\Run` mechanism for disable tracking
72+
- Visual feedback with disabled items shown in gray italic
73+
- Requires admin rights for system-level items
74+
- 🚧 **Delete Startup Items**: Permanently removes from Run/RunOnce with confirmation
75+
- 🚧 **Backup to .REG File**: Export startup registry entries for restoration
76+
- 🚧 **Grid Display**: Columns: Enabled (checkbox), Name, Publisher, Command, Location (UserRun/SystemRun/etc)
77+
- 🚧 **Windows System Filtering**: Filters out built-in Windows startup programs
78+
- 🚧 **Publisher Detection**: Auto-detects software vendors from common path patterns
79+
6280
### 4. Essential Features ✅ **IMPLEMENTED**
6381
-**Column Sorting**: DataGrid supports sorting by clicking any column header
6482
-**Column Width Management**: Menu Text auto-sizes to content, File column takes remaining space
@@ -110,9 +128,11 @@ To provide Windows users with a simple, safe, and comprehensive tool for customi
110128

111129
## User Interface Requirements
112130

113-
### Main Window Layout ✅ **IMPLEMENTED** (Simplified from CCleaner Design)
114-
-**Single Unified View**: No tabs - single DataGrid with Type column for all context menu types
115-
- **Design Decision**: Simpler, more efficient than tabs. Users can sort by Type to group items.
131+
### Main Window Layout ✅ **IMPLEMENTED** with 🚧 **Tabs for Separate Features**
132+
-**Tab-Based Navigation**: Separate tabs for independent features
133+
- **Context Menus Tab**: Single unified DataGrid with Type column (File/Directory/Drive/Background)
134+
- 🚧 **Startup Programs Tab**: Dedicated view for Windows startup management
135+
- **Design Decision**: Tabs for completely different features (context menus vs. startup), unified view within each feature
116136
-**Data Grid View**: Displays:
117137
- **Enabled Column**: Checkbox with INotifyPropertyChanged binding for instant toggle
118138
- **Type Column**: Shows File, Directory, Drive, or Background
@@ -278,4 +298,52 @@ ContextMenuEditor/
278298
- **User Feedback Driven**: Iterated based on actual usage feedback
279299

280300
## Conclusion
281-
Context Menu Editor v1.0 successfully provides Windows users with a clean, powerful tool to manage their context menus efficiently and safely, eliminating the need for direct registry editing while maintaining full control over the user experience. The application delivers on its core promise with a focus on simplicity, safety, and usability.
301+
Context Menu Editor v1.0 successfully provides Windows users with a clean, powerful tool to manage their context menus efficiently and safely, eliminating the need for direct registry editing while maintaining full control over the user experience. The application delivers on its core promise with a focus on simplicity, safety, and usability.
302+
303+
---
304+
305+
## v1.1 Development Notes (In Progress)
306+
307+
### New Feature: Windows Startup Management
308+
309+
**Goal**: Expand the application to manage Windows startup programs, following the same architectural patterns and UI principles as the context menu management.
310+
311+
**Implementation Approach**:
312+
1. **Separate Tab**: Added "Startup Programs" tab alongside "Context Menus" tab
313+
- Each tab represents a completely different feature
314+
- Maintains design principle: unified view within each feature, tabs for separate features
315+
2. **New Models**: `StartupItem` with properties: Name, Command, Publisher, Location, IsEnabled, RegistryPath
316+
3. **New Service**: `StartupService` implementing `IStartupService` for registry operations
317+
- Discovers items from Run and RunOnce keys (User and System level)
318+
- Enable/Disable using Windows 10+ `StartupApproved` mechanism
319+
- Delete operations with confirmation
320+
- Backup to .REG file format
321+
4. **New ViewModel**: `StartupViewModel` following same pattern as `MainViewModel`
322+
- ObservableCollection of startup items
323+
- Enable/Disable/Delete/Backup/Refresh commands
324+
- Status messages and loading states
325+
5. **New View**: `StartupView` UserControl with same layout as context menu view
326+
- DataGrid with columns: Enabled, Name, Publisher, Command, Location
327+
- Action buttons panel on the right
328+
- Status bar at bottom
329+
6. **Consistent Patterns**: Reuses existing infrastructure
330+
- ViewModelBase for INotifyPropertyChanged
331+
- RelayCommand for commands
332+
- Same styling and theming from App.xaml
333+
- Similar enable/disable/delete workflows
334+
335+
**Registry Locations**:
336+
- **User Run**: `HKCU\Software\Microsoft\Windows\CurrentVersion\Run`
337+
- **System Run**: `HKLM\Software\Microsoft\Windows\CurrentVersion\Run`
338+
- **User RunOnce**: `HKCU\Software\Microsoft\Windows\CurrentVersion\RunOnce`
339+
- **System RunOnce**: `HKLM\Software\Microsoft\Windows\CurrentVersion\RunOnce`
340+
- **Disable Tracking**: `HKCU/HKLM\...\Explorer\StartupApproved\Run` (Windows 10+)
341+
342+
**Testing Status**: 🚧 In Progress
343+
- ✅ Code compiles successfully
344+
- ⏳ Runtime testing with admin privileges required
345+
- ⏳ Verify enable/disable functionality
346+
- ⏳ Test delete operations
347+
- ⏳ Validate backup/restore workflow
348+
349+
**Version**: This will be released as v1.1 using semantic versioning (MINOR) marker in commit message.

Services/IStartupService.cs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
using System.Collections.Generic;
2+
using System.Threading.Tasks;
3+
4+
namespace ContextMenuEditor.Services;
5+
6+
/// <summary>
7+
/// Interface for managing Windows startup entries.
8+
/// Follows the Dependency Inversion Principle.
9+
/// </summary>
10+
public interface IStartupService
11+
{
12+
/// <summary>
13+
/// Discovers all startup entries from the Windows registry.
14+
/// </summary>
15+
/// <returns>List of discovered startup items.</returns>
16+
Task<List<Models.StartupItem>> DiscoverStartupItemsAsync();
17+
18+
/// <summary>
19+
/// Enables a startup item in the registry.
20+
/// </summary>
21+
/// <param name="item">The item to enable.</param>
22+
/// <returns>True if successful, false otherwise.</returns>
23+
Task<bool> EnableItemAsync(Models.StartupItem item);
24+
25+
/// <summary>
26+
/// Disables a startup item in the registry.
27+
/// </summary>
28+
/// <param name="item">The item to disable.</param>
29+
/// <returns>True if successful, false otherwise.</returns>
30+
Task<bool> DisableItemAsync(Models.StartupItem item);
31+
32+
/// <summary>
33+
/// Deletes a startup item from the registry.
34+
/// </summary>
35+
/// <param name="item">The item to delete.</param>
36+
/// <returns>True if successful, false otherwise.</returns>
37+
Task<bool> DeleteItemAsync(Models.StartupItem item);
38+
39+
/// <summary>
40+
/// Creates a backup of startup registry entries to a .reg file.
41+
/// </summary>
42+
/// <param name="items">List of startup items to backup.</param>
43+
/// <param name="filePath">Path where the .reg file should be saved.</param>
44+
/// <returns>True if successful, false otherwise.</returns>
45+
Task<bool> CreateBackupAsync(List<Models.StartupItem> items, string filePath);
46+
}

0 commit comments

Comments
 (0)