新增工具/组合随软件启动自动运行功能
- ToolItem 模型新增 AutoRunOnStart 属性,持久化到配置文件 - App.OnStartup 启动后自动执行标记为自启动的工具/组合(间隔500ms) - 工具编辑窗口和组合编辑窗口新增「随软件启动自动运行」CheckBox - 主界面工具卡片左上角 Rocket 角标标识已启用自启的项目
This commit is contained in:
@@ -34,7 +34,7 @@ public partial class App : System.Windows.Application
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnStartup(StartupEventArgs e)
|
protected override async void OnStartup(StartupEventArgs e)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -49,6 +49,7 @@ public partial class App : System.Windows.Application
|
|||||||
dataService.Load();
|
dataService.Load();
|
||||||
|
|
||||||
var mainWindow = Services.GetRequiredService<MainWindow>();
|
var mainWindow = Services.GetRequiredService<MainWindow>();
|
||||||
|
var mainViewModel = Services.GetRequiredService<ViewModels.MainViewModel>();
|
||||||
|
|
||||||
// -autostart 参数:开机自启时隐藏窗口
|
// -autostart 参数:开机自启时隐藏窗口
|
||||||
if (e.Args.Contains("-autostart", StringComparer.OrdinalIgnoreCase))
|
if (e.Args.Contains("-autostart", StringComparer.OrdinalIgnoreCase))
|
||||||
@@ -59,6 +60,9 @@ public partial class App : System.Windows.Application
|
|||||||
{
|
{
|
||||||
mainWindow.Show();
|
mainWindow.Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 启动标记为自动运行的工具和组合
|
||||||
|
await mainViewModel.ExecuteAutoRunToolsAsync();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -57,4 +57,9 @@ public class ToolItem
|
|||||||
/// 当 IsGroup 为 true 时,存储需批量启动的子工具 ID 列表
|
/// 当 IsGroup 为 true 时,存储需批量启动的子工具 ID 列表
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public List<string> SubToolIds { get; set; } = new();
|
public List<string> SubToolIds { get; set; } = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否在软件启动时自动运行
|
||||||
|
/// </summary>
|
||||||
|
public bool AutoRunOnStart { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,6 +35,9 @@ public partial class GroupEditViewModel : ObservableObject
|
|||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private IconProvider.IconOption? _selectedIcon;
|
private IconProvider.IconOption? _selectedIcon;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private bool _autoRunOnStart;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 可供勾选的普通工具列表(IsGroup == false)
|
/// 可供勾选的普通工具列表(IsGroup == false)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -85,6 +88,7 @@ public partial class GroupEditViewModel : ObservableObject
|
|||||||
Name = groupToEdit.Name;
|
Name = groupToEdit.Name;
|
||||||
HotKey = groupToEdit.HotKey;
|
HotKey = groupToEdit.HotKey;
|
||||||
SelectedCategory = Categories.FirstOrDefault(c => c.Id == groupToEdit.CategoryId);
|
SelectedCategory = Categories.FirstOrDefault(c => c.Id == groupToEdit.CategoryId);
|
||||||
|
AutoRunOnStart = groupToEdit.AutoRunOnStart;
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(groupToEdit.IconCode))
|
if (!string.IsNullOrEmpty(groupToEdit.IconCode))
|
||||||
{
|
{
|
||||||
@@ -119,6 +123,7 @@ public partial class GroupEditViewModel : ObservableObject
|
|||||||
_editingGroup.CategoryId = SelectedCategory?.Id ?? string.Empty;
|
_editingGroup.CategoryId = SelectedCategory?.Id ?? string.Empty;
|
||||||
_editingGroup.SubToolIds = selectedIds;
|
_editingGroup.SubToolIds = selectedIds;
|
||||||
_editingGroup.IsValid = true;
|
_editingGroup.IsValid = true;
|
||||||
|
_editingGroup.AutoRunOnStart = AutoRunOnStart;
|
||||||
_logService.Info($"已更新组合: {Name.Trim()}(包含 {selectedIds.Count} 个工具)");
|
_logService.Info($"已更新组合: {Name.Trim()}(包含 {selectedIds.Count} 个工具)");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -131,7 +136,8 @@ public partial class GroupEditViewModel : ObservableObject
|
|||||||
CategoryId = SelectedCategory?.Id ?? string.Empty,
|
CategoryId = SelectedCategory?.Id ?? string.Empty,
|
||||||
IsGroup = true,
|
IsGroup = true,
|
||||||
SubToolIds = selectedIds,
|
SubToolIds = selectedIds,
|
||||||
IsValid = true
|
IsValid = true,
|
||||||
|
AutoRunOnStart = AutoRunOnStart
|
||||||
});
|
});
|
||||||
_logService.Info($"已添加组合: {Name.Trim()}(包含 {selectedIds.Count} 个工具)");
|
_logService.Info($"已添加组合: {Name.Trim()}(包含 {selectedIds.Count} 个工具)");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -257,6 +257,24 @@ public partial class MainViewModel : ObservableObject
|
|||||||
RefreshData();
|
RefreshData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ───────────────────────────── 自动运行 ─────────────────────────────
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 启动时自动运行标记为 AutoRunOnStart 的工具和组合
|
||||||
|
/// </summary>
|
||||||
|
public async Task ExecuteAutoRunToolsAsync()
|
||||||
|
{
|
||||||
|
var autoTools = _dataService.Config.Tools.Where(t => t.AutoRunOnStart).ToList();
|
||||||
|
if (autoTools.Count == 0) return;
|
||||||
|
|
||||||
|
_logService.Info($"正在启动 {autoTools.Count} 个自启动工具...");
|
||||||
|
foreach (var tool in autoTools)
|
||||||
|
{
|
||||||
|
await _processService.ExecuteAsync(tool);
|
||||||
|
await Task.Delay(500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ───────────────────────────── 数据刷新 ─────────────────────────────
|
// ───────────────────────────── 数据刷新 ─────────────────────────────
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -43,6 +43,9 @@ public partial class ToolEditViewModel : ObservableObject
|
|||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private IconProvider.IconOption? _selectedIcon;
|
private IconProvider.IconOption? _selectedIcon;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private bool _autoRunOnStart;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 分类下拉列表
|
/// 分类下拉列表
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -87,6 +90,7 @@ public partial class ToolEditViewModel : ObservableObject
|
|||||||
Arguments = toolToEdit.Arguments;
|
Arguments = toolToEdit.Arguments;
|
||||||
HotKey = toolToEdit.HotKey;
|
HotKey = toolToEdit.HotKey;
|
||||||
SelectedCategory = Categories.FirstOrDefault(c => c.Id == toolToEdit.CategoryId);
|
SelectedCategory = Categories.FirstOrDefault(c => c.Id == toolToEdit.CategoryId);
|
||||||
|
AutoRunOnStart = toolToEdit.AutoRunOnStart;
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(toolToEdit.IconCode))
|
if (!string.IsNullOrEmpty(toolToEdit.IconCode))
|
||||||
{
|
{
|
||||||
@@ -149,6 +153,7 @@ public partial class ToolEditViewModel : ObservableObject
|
|||||||
_editingTool.HotKey = HotKey.Trim();
|
_editingTool.HotKey = HotKey.Trim();
|
||||||
_editingTool.CategoryId = SelectedCategory?.Id ?? string.Empty;
|
_editingTool.CategoryId = SelectedCategory?.Id ?? string.Empty;
|
||||||
_editingTool.IsValid = IsExecutablePathValid(ExecutablePath.Trim());
|
_editingTool.IsValid = IsExecutablePathValid(ExecutablePath.Trim());
|
||||||
|
_editingTool.AutoRunOnStart = AutoRunOnStart;
|
||||||
|
|
||||||
_logService.Info($"已更新工具: {Name.Trim()}");
|
_logService.Info($"已更新工具: {Name.Trim()}");
|
||||||
}
|
}
|
||||||
@@ -163,7 +168,8 @@ public partial class ToolEditViewModel : ObservableObject
|
|||||||
Arguments = Arguments.Trim(),
|
Arguments = Arguments.Trim(),
|
||||||
HotKey = HotKey.Trim(),
|
HotKey = HotKey.Trim(),
|
||||||
CategoryId = SelectedCategory?.Id ?? string.Empty,
|
CategoryId = SelectedCategory?.Id ?? string.Empty,
|
||||||
IsValid = IsExecutablePathValid(ExecutablePath.Trim())
|
IsValid = IsExecutablePathValid(ExecutablePath.Trim()),
|
||||||
|
AutoRunOnStart = AutoRunOnStart
|
||||||
};
|
};
|
||||||
|
|
||||||
_dataService.Config.Tools.Add(newTool);
|
_dataService.Config.Tools.Add(newTool);
|
||||||
|
|||||||
@@ -105,6 +105,7 @@
|
|||||||
<RowDefinition Height="Auto"/>
|
<RowDefinition Height="Auto"/>
|
||||||
<RowDefinition Height="*"/>
|
<RowDefinition Height="*"/>
|
||||||
<RowDefinition Height="Auto"/>
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="70"/>
|
<ColumnDefinition Width="70"/>
|
||||||
@@ -185,12 +186,20 @@
|
|||||||
VerticalContentAlignment="Center"
|
VerticalContentAlignment="Center"
|
||||||
Height="28" Margin="0,0,0,10" Padding="6,0"/>
|
Height="28" Margin="0,0,0,10" Padding="6,0"/>
|
||||||
|
|
||||||
|
<!-- 自动运行 -->
|
||||||
|
<CheckBox Grid.Row="4" Grid.Column="1"
|
||||||
|
IsChecked="{Binding AutoRunOnStart}"
|
||||||
|
Content="随软件启动自动运行"
|
||||||
|
Foreground="{DynamicResource Theme.Foreground}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Margin="0,0,0,10"/>
|
||||||
|
|
||||||
<!-- 子工具选择 -->
|
<!-- 子工具选择 -->
|
||||||
<TextBlock Grid.Row="4" Grid.Column="0"
|
<TextBlock Grid.Row="5" Grid.Column="0"
|
||||||
Text="包含工具:"
|
Text="包含工具:"
|
||||||
Foreground="{DynamicResource Theme.Foreground}"
|
Foreground="{DynamicResource Theme.Foreground}"
|
||||||
VerticalAlignment="Top" Margin="0,4,0,0"/>
|
VerticalAlignment="Top" Margin="0,4,0,0"/>
|
||||||
<Border Grid.Row="4" Grid.Column="1"
|
<Border Grid.Row="5" Grid.Column="1"
|
||||||
Background="{DynamicResource Theme.InputBackground}"
|
Background="{DynamicResource Theme.InputBackground}"
|
||||||
BorderBrush="{DynamicResource Theme.InputBorder}"
|
BorderBrush="{DynamicResource Theme.InputBorder}"
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
@@ -230,7 +239,7 @@
|
|||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
<!-- 按钮 -->
|
<!-- 按钮 -->
|
||||||
<StackPanel Grid.Row="6" Grid.Column="1"
|
<StackPanel Grid.Row="7" Grid.Column="1"
|
||||||
Orientation="Horizontal" HorizontalAlignment="Right"
|
Orientation="Horizontal" HorizontalAlignment="Right"
|
||||||
Margin="0,10,0,0">
|
Margin="0,10,0,0">
|
||||||
<Button Content="保存"
|
<Button Content="保存"
|
||||||
|
|||||||
@@ -134,6 +134,23 @@
|
|||||||
</Style>
|
</Style>
|
||||||
</fa:IconBlock.Style>
|
</fa:IconBlock.Style>
|
||||||
</fa:IconBlock>
|
</fa:IconBlock>
|
||||||
|
<!-- 自启动角标 -->
|
||||||
|
<fa:IconBlock Icon="Rocket" FontSize="10"
|
||||||
|
Foreground="{DynamicResource Theme.Accent}"
|
||||||
|
HorizontalAlignment="Left"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
Margin="6,4,0,0">
|
||||||
|
<fa:IconBlock.Style>
|
||||||
|
<Style TargetType="fa:IconBlock">
|
||||||
|
<Setter Property="Visibility" Value="Collapsed"/>
|
||||||
|
<Style.Triggers>
|
||||||
|
<DataTrigger Binding="{Binding AutoRunOnStart}" Value="True">
|
||||||
|
<Setter Property="Visibility" Value="Visible"/>
|
||||||
|
</DataTrigger>
|
||||||
|
</Style.Triggers>
|
||||||
|
</Style>
|
||||||
|
</fa:IconBlock.Style>
|
||||||
|
</fa:IconBlock>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Border>
|
</Border>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
|
|||||||
@@ -106,6 +106,7 @@
|
|||||||
<RowDefinition Height="Auto"/>
|
<RowDefinition Height="Auto"/>
|
||||||
<RowDefinition Height="Auto"/>
|
<RowDefinition Height="Auto"/>
|
||||||
<RowDefinition Height="Auto"/>
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
<RowDefinition Height="*"/>
|
<RowDefinition Height="*"/>
|
||||||
<RowDefinition Height="Auto"/>
|
<RowDefinition Height="Auto"/>
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
@@ -229,13 +230,21 @@
|
|||||||
Foreground="{DynamicResource Theme.TextSecondary}"
|
Foreground="{DynamicResource Theme.TextSecondary}"
|
||||||
FontSize="11" Margin="0,0,0,16"/>
|
FontSize="11" Margin="0,0,0,16"/>
|
||||||
|
|
||||||
|
<!-- 自动运行 -->
|
||||||
|
<CheckBox Grid.Row="7" Grid.Column="1" Grid.ColumnSpan="2"
|
||||||
|
IsChecked="{Binding AutoRunOnStart}"
|
||||||
|
Content="随软件启动自动运行"
|
||||||
|
Foreground="{DynamicResource Theme.Foreground}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Margin="0,0,0,12"/>
|
||||||
|
|
||||||
<!-- 分隔线 -->
|
<!-- 分隔线 -->
|
||||||
<Border Grid.Row="7" Grid.ColumnSpan="3"
|
<Border Grid.Row="8" Grid.ColumnSpan="3"
|
||||||
BorderBrush="{DynamicResource Theme.CardBorder}"
|
BorderBrush="{DynamicResource Theme.CardBorder}"
|
||||||
BorderThickness="0,1,0,0" Margin="0,0,0,14"/>
|
BorderThickness="0,1,0,0" Margin="0,0,0,14"/>
|
||||||
|
|
||||||
<!-- 按钮 -->
|
<!-- 按钮 -->
|
||||||
<StackPanel Grid.Row="8" Grid.Column="1" Grid.ColumnSpan="2"
|
<StackPanel Grid.Row="9" Grid.Column="1" Grid.ColumnSpan="2"
|
||||||
Orientation="Horizontal" HorizontalAlignment="Right">
|
Orientation="Horizontal" HorizontalAlignment="Right">
|
||||||
<Button Content="保存"
|
<Button Content="保存"
|
||||||
Command="{Binding SaveCommand}"
|
Command="{Binding SaveCommand}"
|
||||||
|
|||||||
Reference in New Issue
Block a user