|
|
@@ -14,10 +14,26 @@ namespace MvvmScaffoldFrame48.DLL.SystemTools
|
|
|
/// 若出现自启动时相对路径异常的情况可以在程序启动时引用如下代码
|
|
|
/// Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory);
|
|
|
/// </summary>
|
|
|
+
|
|
|
+ #region 注册表实现(WIN11无效)
|
|
|
// 注册表路径
|
|
|
private static readonly string RegistryPath = @"Software\Microsoft\Windows\CurrentVersion\Run";
|
|
|
// 应用名称,作为注册表键名
|
|
|
- private static readonly string AppName = "CCDCount";
|
|
|
+ private static readonly string AppName = "MvvmScffold";
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 获取当前可执行文件路径(带引号,用于注册表)
|
|
|
+ /// </summary>
|
|
|
+ public static string GetExecutablePathForRegistry()
|
|
|
+ {
|
|
|
+ string path = Process.GetCurrentProcess().MainModule.FileName;
|
|
|
+ // 如果路径包含空格,必须用双引号包裹
|
|
|
+ if (path.Contains(" "))
|
|
|
+ {
|
|
|
+ return $"\"{path}\"";
|
|
|
+ }
|
|
|
+ return path;
|
|
|
+ }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 获取当前可执行文件路径
|
|
|
@@ -55,7 +71,7 @@ namespace MvvmScaffoldFrame48.DLL.SystemTools
|
|
|
{
|
|
|
if (!IsAutoStart())
|
|
|
{
|
|
|
- key.SetValue(AppName, GetExecutablePath());
|
|
|
+ key.SetValue(AppName, GetExecutablePathForRegistry());
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
@@ -65,5 +81,190 @@ namespace MvvmScaffoldFrame48.DLL.SystemTools
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region 任务计划程序实现(兼容性高,BUG未测试)
|
|
|
+ private const string TaskName = "MvvmScffold";
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 检查任务是否已注册且处于启用状态
|
|
|
+ /// </summary>
|
|
|
+ /// <returns>true: 已注册且启用; false: 未注册或已禁用</returns>
|
|
|
+ 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;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 创建或更新开机自启任务
|
|
|
+ /// </summary>
|
|
|
+ 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}");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 删除开机自启任务
|
|
|
+ /// </summary>
|
|
|
+ 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}");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ #endregion
|
|
|
}
|
|
|
}
|