using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CCDCount.DLL.Tools
{
public class AutoStartHelper
{
// 注册表路径
private static readonly string RegistryPath = @"Software\Microsoft\Windows\CurrentVersion\Run";
// 应用名称,作为注册表键名
private static readonly string AppName = "CCDCount";
///
/// 获取当前可执行文件路径(带引号,用于注册表)
///
public static string GetExecutablePathForRegistry()
{
string path = Process.GetCurrentProcess().MainModule.FileName;
// 如果路径包含空格,必须用双引号包裹
if (path.Contains(" "))
{
return $"\"{path}\"";
}
return path;
}
///
/// 获取当前可执行文件路径
///
public static string GetExecutablePath()
{
return Process.GetCurrentProcess().MainModule.FileName;
}
///
/// 检查是否已设置自启动
///
public static bool IsAutoStart()
{
using (var key = Registry.CurrentUser.OpenSubKey(RegistryPath, false))
{
if (key == null) return false;
var value = key.GetValue(AppName);
// 验证路径是否一致,防止exe移动后失效
return value != null && value.ToString() == GetExecutablePath();
}
}
///
/// 设置或取消自启动
///
/// true 为启用,false 为禁用
public static void SetAutoStart(bool isAutoStart)
{
using (var key = Registry.CurrentUser.OpenSubKey(RegistryPath, true))
{
if (key == null) return;
if (isAutoStart)
{
if (!IsAutoStart())
{
key.SetValue(AppName, GetExecutablePathForRegistry());
}
}
else
{
// false 参数表示值不存在时不抛出异常
key.DeleteValue(AppName, false);
}
}
}
private const string TaskName = "CCDCount";
///
/// 检查任务是否已注册且处于启用状态
///
/// true: 已注册且启用; false: 未注册或已禁用
public static bool IsTaskRegisteredAndEnabled()
{
try
{
// 查询任务状态
// /fo LIST 以列表格式输出
// /v 显示详细信息
string arguments = $"/query /tn \"{TaskName}\" /fo LIST /v";
ProcessStartInfo startInfo = new ProcessStartInfo
{
FileName = "schtasks",
Arguments = arguments,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true
};
using (Process process = Process.Start(startInfo))
{
string output = process.StandardOutput.ReadToEnd();
process.WaitForExit();
if (process.ExitCode == 0)
{
// 检查输出中是否包含 "Status: Ready" 或 "State: Enabled"
// 不同语言版本的Windows输出可能略有不同,通常检查 "Ready" 或 "Enabled"
// 英文系统: "Status: Ready"
// 中文系统: "状态: 就绪"
// 更通用的方法是检查是否存在该任务名,且没有报错
// 如果需要严格判断是否启用,可以解析输出中的 "Status" 行
if (output.Contains("Ready") || output.Contains("就绪"))
{
return true;
}
// 如果任务是 "Disabled" (禁用) 或 "Disabled" (中文: 已禁用),则返回 false
if (output.Contains("Disabled") || output.Contains("已禁用"))
{
return false;
}
// 其他状态视为未准备好
return false;
}
else
{
// 退出码非0,通常意味着任务不存在 (ERROR: The system cannot find the file specified.)
return false;
}
}
}
catch (Exception)
{
// 发生异常时,保守地认为未注册,以便后续尝试重新注册
return false;
}
}
///
/// 创建或更新开机自启任务
///
public static void RegisterTask()
{
// 1. 先检查是否已经正确配置
if (IsTaskRegisteredAndEnabled())
{
// 可选:进一步检查路径是否一致,如果路径变了也需要更新
// 这里为了简化,如果已启用则直接返回,避免重复弹窗
Console.WriteLine("任务已存在且处于启用状态,无需操作。");
return;
}
try
{
string exePath = Process.GetCurrentProcess().MainModule.FileName;
// 构建 schtasks 命令
// /ru "" 表示以当前用户运行 (在某些Win11版本中,显式指定用户更稳定)
// /rl highest 表示以最高权限运行
// /sc onlogon 表示登录时触发
// /f 强制覆盖已存在的任务
string arguments = $"/create /tn \"{TaskName}\" /tr \"\\\"{exePath}\\\"\" /sc onlogon /rl highest /f";
ProcessStartInfo startInfo = new ProcessStartInfo
{
FileName = "schtasks",
Arguments = arguments,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
Verb = "runas" // 请求管理员权限
};
using (Process process = Process.Start(startInfo))
{
process.WaitForExit();
if (process.ExitCode == 0)
{
Console.WriteLine("任务计划创建/更新成功");
}
else
{
string error = process.StandardError.ReadToEnd();
Console.WriteLine($"创建失败: {error}");
}
}
}
catch (Exception ex)
{
Console.WriteLine($"异常: {ex.Message}");
}
}
///
/// 删除开机自启任务
///
public static void UnregisterTask()
{
// 可选:先检查是否存在,避免无意义的弹窗
try
{
string checkArgs = $"/query /tn \"{TaskName}\"";
ProcessStartInfo checkInfo = new ProcessStartInfo("schtasks", checkArgs)
{
UseShellExecute = false,
CreateNoWindow = true
};
using (var p = Process.Start(checkInfo))
{
p.WaitForExit();
if (p.ExitCode != 0)
{
Console.WriteLine("任务不存在,无需删除。");
return;
}
}
}
catch { }
try
{
string arguments = $"/delete /tn \"{TaskName}\" /f";
ProcessStartInfo startInfo = new ProcessStartInfo
{
FileName = "schtasks",
Arguments = arguments,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
Verb = "runas"
};
using (Process process = Process.Start(startInfo))
{
process.WaitForExit();
if (process.ExitCode == 0)
{
Console.WriteLine("任务删除成功");
}
else
{
string error = process.StandardError.ReadToEnd();
Console.WriteLine($"删除失败: {error}");
}
}
}
catch (Exception ex)
{
Console.WriteLine($"删除任务失败: {ex.Message}");
}
}
}
}