Skip to content

Commit 6b2fc23

Browse files
committed
#31 使用任务计划实现开机启动
1 parent 5ba2b13 commit 6b2fc23

File tree

7 files changed

+113
-32
lines changed

7 files changed

+113
-32
lines changed

src/ComputerLock/App.xaml.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ private void Init()
8383
var sp = services.BuildServiceProvider();
8484
Resources.Add("services", sp);
8585

86+
// 自动启动迁移:在应用启动时执行一次注册表 -> 计划任务的迁移
87+
sp.GetRequiredService<AutostartHook>().MigrateRegistryToTaskIfNeeded();
88+
8689
var cultureInfo = new CultureInfo(sp.GetRequiredService<AppSettings>().Lang.ToString());
8790
CultureInfo.CurrentCulture = cultureInfo;
8891
Thread.CurrentThread.CurrentCulture = cultureInfo;

src/ComputerLock/Components/Settings/UnlockSettings.razor

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,18 @@
4747
Color="@(isPasswordSelected ? Color.Secondary : Color.Default)" />
4848
</div>
4949
<div class="card-content">
50+
51+
<MudText Typo="Typo.body2" Color="Color.Secondary" Class="mb-4">
52+
@if (AppSettings.EnablePasswordBox)
53+
{
54+
@(Lang["DisablePasswordBoxTips"])
55+
}
56+
else
57+
{
58+
@(Lang["EnablePasswordBoxTips"])
59+
}
60+
</MudText>
61+
5062
<MudButton Color="Color.Secondary"
5163
Variant="Variant.Outlined"
5264
Class="mb-2"
@@ -63,16 +75,6 @@
6375
Dense="true"
6476
Class="no-left-padding max-width-fix"
6577
Disabled="@(!isPasswordSelected)" />
66-
<MudText Typo="Typo.body2" Color="Color.Secondary" Class="input-tip ml-7" Style="opacity: 1">
67-
@if (AppSettings.EnablePasswordBox)
68-
{
69-
@(Lang["DisablePasswordBoxTips"])
70-
}
71-
else
72-
{
73-
@(Lang["EnablePasswordBoxTips"])
74-
}
75-
</MudText>
7678

7779
<MudStack Class="ml-4 mt-4" Spacing="4">
7880
<div>

src/ComputerLock/ComputerLock.csproj

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,9 @@
2323
<PackageReference Include="JiuLing.TitleBarKit" Version="1.0.3" />
2424
<PackageReference Include="Microsoft.AspNetCore.Components.WebView.Wpf" Version="8.0.100" />
2525
<PackageReference Include="ModernWpfUI" Version="0.9.6" />
26-
<PackageReference Include="MudBlazor" Version="8.10.0" />
27-
<PackageReference Include="MudBlazor.Markdown" Version="8.9.0" />
26+
<PackageReference Include="MudBlazor" Version="8.12.0" />
27+
<PackageReference Include="MudBlazor.Markdown" Version="8.11.0" />
28+
<PackageReference Include="TaskScheduler" Version="2.12.2" />
2829
</ItemGroup>
2930

3031
<ItemGroup>
Lines changed: 89 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,110 @@
11
using Microsoft.Win32;
2+
using Microsoft.Win32.TaskScheduler;
3+
using System.IO;
24

35
namespace ComputerLock.Platforms;
4-
internal class AutostartHook
6+
internal class AutostartHook(ILogger logger)
57
{
6-
private const string RegKey = @"Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Run";
8+
private const string TaskName = "ComputerLockAutoStart";
9+
10+
11+
/// <summary>
12+
/// 迁移老版本中的注册表自启动项到计划任务
13+
/// </summary>
14+
public void MigrateRegistryToTaskIfNeeded()
15+
{
16+
try
17+
{
18+
const string regKey = @"Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Run";
19+
var registryKey = Registry.LocalMachine.OpenSubKey(regKey);
20+
if (registryKey?.GetValue(AppBase.FriendlyName) == null)
21+
{
22+
return;
23+
}
24+
CreateOrUpdateTask();
25+
using var registryKeyWrite = Registry.LocalMachine.CreateSubKey(regKey);
26+
registryKeyWrite.DeleteValue(AppBase.FriendlyName);
27+
}
28+
catch (Exception ex)
29+
{
30+
logger.Error("迁移自启动项失败", ex);
31+
}
32+
}
33+
734
public bool IsAutostart()
835
{
9-
var registryKey = Registry.LocalMachine.OpenSubKey(RegKey);
10-
if (registryKey == null)
36+
// 判断计划任务是否存在
37+
try
1138
{
12-
return false;
39+
using var taskService = new TaskService();
40+
var task = taskService.GetTask(TaskName);
41+
return task != null;
1342
}
14-
if (registryKey.GetValue(AppBase.FriendlyName) == null)
43+
catch (Exception ex)
1544
{
45+
logger.Error("任务计划获取失败", ex);
1646
return false;
1747
}
18-
return true;
1948
}
2049

2150
public void EnabledAutostart()
2251
{
23-
string execPath = AppBase.ExecutablePath;
24-
var registryKey = Registry.LocalMachine.CreateSubKey(RegKey);
25-
registryKey.SetValue(AppBase.FriendlyName, $"\"{execPath}\"");
26-
registryKey.Close();
52+
CreateOrUpdateTask();
2753
}
2854

2955
public void DisabledAutostart()
3056
{
31-
var registryKey = Registry.LocalMachine.CreateSubKey(RegKey);
32-
registryKey.DeleteValue(AppBase.FriendlyName);
33-
registryKey.Close();
57+
DeleteTaskIfExists();
58+
}
59+
60+
private void CreateOrUpdateTask()
61+
{
62+
try
63+
{
64+
using var ts = new TaskService();
65+
66+
// 构建任务定义
67+
var td = ts.NewTask();
68+
td.RegistrationInfo.Description = "透明锁屏开机自动启动任务";
69+
td.Principal.LogonType = TaskLogonType.InteractiveToken;
70+
td.Principal.RunLevel = TaskRunLevel.Highest;
71+
td.Settings.MultipleInstances = TaskInstancesPolicy.IgnoreNew;
72+
td.Settings.DisallowStartIfOnBatteries = false;
73+
td.Settings.StopIfGoingOnBatteries = false;
74+
td.Settings.StartWhenAvailable = true;
75+
76+
// 触发器:用户登录
77+
td.Triggers.Add(new LogonTrigger());
78+
79+
// 操作:启动程序
80+
var execPath = AppBase.ExecutablePath;
81+
var workingDir = Path.GetDirectoryName(execPath);
82+
td.Actions.Add(new ExecAction(execPath, null, workingDir));
83+
84+
// 注册(创建或更新)
85+
ts.RootFolder.RegisterTaskDefinition(TaskName, td, TaskCreation.CreateOrUpdate, null, null, TaskLogonType.InteractiveToken);
86+
87+
}
88+
catch (Exception ex)
89+
{
90+
logger.Error("任务计划创建失败", ex);
91+
}
92+
}
93+
94+
private void DeleteTaskIfExists()
95+
{
96+
try
97+
{
98+
using var taskService = new TaskService();
99+
var task = taskService.GetTask(TaskName);
100+
if (task != null)
101+
{
102+
taskService.RootFolder.DeleteTask(TaskName);
103+
}
104+
}
105+
catch (Exception ex)
106+
{
107+
logger.Error("任务计划删除失败", ex);
108+
}
34109
}
35110
}

src/ComputerLock/Resources/Lang.Designer.cs

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/ComputerLock/Resources/Lang.resx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@
241241
<value>已解锁</value>
242242
</data>
243243
<data name="EnablePasswordBoxTips" xml:space="preserve">
244-
<value>解锁方式:按 [ESC] 键,然后直接输入密码</value>
244+
<value>当前解锁方式:按 [ESC] 键,然后直接输入密码</value>
245245
</data>
246246
<data name="LogFiles" xml:space="preserve">
247247
<value>日志文件</value>
@@ -430,6 +430,6 @@
430430
<value>网络请求失败,请稍后再试。</value>
431431
</data>
432432
<data name="DisablePasswordBoxTips" xml:space="preserve">
433-
<value>解锁方式:按 [ESC] 键 或 鼠标点击密码框位置显示密码框</value>
433+
<value>当前解锁方式:按 [ESC] 键 或 鼠标点击密码框位置显示密码框</value>
434434
</data>
435435
</root>

src/ComputerLock/Resources/Lang.zh.resx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@
241241
<value>已解锁</value>
242242
</data>
243243
<data name="EnablePasswordBoxTips" xml:space="preserve">
244-
<value>解锁方式:按 [ESC] 键,然后直接输入密码</value>
244+
<value>当前解锁方式:按 [ESC] 键,然后直接输入密码</value>
245245
</data>
246246
<data name="LogFiles" xml:space="preserve">
247247
<value>日志文件</value>
@@ -430,6 +430,6 @@
430430
<value>网络请求失败,请稍后再试。</value>
431431
</data>
432432
<data name="DisablePasswordBoxTips" xml:space="preserve">
433-
<value>解锁方式:按 [ESC] 键 或 鼠标点击密码框位置显示密码框</value>
433+
<value>当前解锁方式:按 [ESC] 键 或 鼠标点击密码框位置显示密码框</value>
434434
</data>
435435
</root>

0 commit comments

Comments
 (0)