C# 程序开机自启
在 Windows 系统中,可以通过以下方式实现程序开机自启。
- 启动文件夹
- 注册表
- 任务计划程序
- 服务
启动文件夹
将需要开机自启程序的快捷方式放入启动文件夹中,即可实现程序开机自启,删除快捷方式就可以取消程序开机自启。
在 C#创建快捷方式需要添加引用 -> COM -> Windows Script Host Object Model
C:\Users<用户名>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
仅对当前用户有效,C#实现代码如下:
/// <summary>
/// 启动文件夹(当前用户)
/// </summary>
/// <param name="exePath">需要开机自启的程序路径</param>
static void AutoStartup1(string exePath)
{
// 获取当前用户的启动文件夹
string path = Environment.GetFolderPath(Environment.SpecialFolder.Startup);
// 判断快捷方式是否已经存在
bool exist = false;
string[] files = Directory.GetFiles(path, "*.lnk");
foreach (var item in files)
{
WshShell shell = new WshShell();
IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(item);
// Console.WriteLine($"{item} {shortcut.TargetPath}");
if (shortcut.TargetPath == exePath)
{
exist = true;
break;
}
}
if (exist)
{
Console.WriteLine("快捷方式已经存在。");
return;
}
// 创建快捷方式
CreateShortcut($"{Path.Combine(path, "Demo4AutoStartup.lnk")}", exePath);
}
创建快捷方式的代码如下:
/// <summary>
/// 创建快捷方式
/// </summary>
/// <param name="shortcutPath"></param>
/// <param name="targetPath"></param>
static void CreateShortcut(string shortcutPath, string targetPath)
{
var shell = new WshShell();
var shortcut = (IWshShortcut)shell.CreateShortcut(shortcutPath);
shortcut.TargetPath = $"{targetPath}";
// 可选,设置程序启动参数
// shortcut.Arguments = "";
shortcut.WorkingDirectory = Path.GetDirectoryName(targetPath);
shortcut.IconLocation = targetPath;
shortcut.Save();
}
C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup
对所有用户有效,C#实现代码如下:
/// <summary>
/// 启动文件夹(所有用户),运行时需要管理员权限
/// </summary>
/// <param name="exePath">需要开机自启的程序路径</param>
static void AutoStartup2(string exePath)
{
// 获取所有用户的启动文件夹
string path = Environment.GetFolderPath(Environment.SpecialFolder.CommonStartup);
// 判断快捷方式是否已经存在
bool exist = false;
string[] files = Directory.GetFiles(path, "*.lnk");
foreach (var item in files)
{
WshShell shell = new WshShell();
IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(item);
// Console.WriteLine($"{item} {shortcut.TargetPath}");
if (shortcut.TargetPath == exePath)
{
exist = true;
break;
}
}
if (exist)
{
Console.WriteLine("快捷方式已经存在。");
return;
}
// 创建快捷方式
CreateShortcut($"{Path.Combine(path, "Demo4AutoStartup.lnk")}", exePath);
}
创建成功后,可以在上述文件夹中看到快捷方式。
注册表
在注册表指定位置写入值,即可实现程序开机自启,删除值就可以取消程序开机自启。
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
仅对当前用户有效,C#实现代码如下:
/// <summary>
/// 注册表(当前用户)
/// </summary>
/// <param name="exePath"></param>
/// <param name="name"></param>
static void AutoStartup3(string exePath, string name)
{
// 判断注册表项是否已经存在
bool exist = false;
using (RegistryKey key = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", true))
{
if (key != null)
{
string[] valueNames = key.GetValueNames();
foreach (string valueName in valueNames)
{
string valueData = key.GetValue(valueName).ToString();
//Console.WriteLine($"{valueName} {valueData}");
if (valueData.Contains(exePath))
{
exist = true;
break;
}
}
if (exist)
{
Console.WriteLine("注册表项已经存在。");
return;
}
key.SetValue(name, exePath);
// 取消开机自启,删除注册表项即可
// key.DeleteValue(name, false);
}
}
}
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
对所有用户有效,C#实现代码如下:
/// <summary>
/// 注册表(所有用户),运行时需要管理员权限
/// </summary>
/// <param name="exePath"></param>
/// <param name="name"></param>
static void AutoStartup4(string exePath, string name)
{
// 判断注册表项是否已经存在
bool exist = false;
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", true))
{
if (key != null)
{
string[] valueNames = key.GetValueNames();
foreach (string valueName in valueNames)
{
string valueData = key.GetValue(valueName).ToString();
Console.WriteLine($"{valueName} {valueData}");
if (valueData.Contains(exePath))
{
exist = true;
break;
}
}
if (exist)
{
Console.WriteLine("注册表项已经存在。");
return;
}
// 我电脑 Windows 10专业版22H2,测试发现注册表项写入在:
// HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Run
key.SetValue(name, exePath);
// 取消开机自启,删除注册表项即可
// key.DeleteValue(name, false);
}
}
}
创建成功后,可以在上述注册表位置看到值,如下图所示:
任务计划程序
任务计划程序介绍及使用可以参考微软官方文档:https://learn.microsoft.com/zh-cn/windows/win32/taskschd/task-scheduler-start-page
C# 可以通过使用第三方库:TaskScheduler 来创建任务,在 NuGet 中搜索安装即可。
C#实现代码如下:
/// <summary>
/// 任务计划程序,运行时需要管理员权限
/// </summary>
/// <param name="exePath"></param>
/// <param name="taskName"></param>
static void AutoStartup5(string exePath, string taskName)
{
using (TaskService taskService = new TaskService())
{
// 创建一个新任务
TaskDefinition taskDefinition = taskService.NewTask();
// 设置任务的触发器为系统启动
taskDefinition.Triggers.Add(new LogonTrigger());
// 设置要运行的程序或脚本
taskDefinition.Actions.Add(new ExecAction(exePath, null, Path.GetDirectoryName(exePath)));
// 注册任务
taskService.RootFolder.RegisterTaskDefinition(taskName, taskDefinition);
// 取消开机自启,删除任务即可
// taskService.RootFolder.DeleteTask(taskName, false);
}
}
创建成功后,可以在任务计划程序看到任务,如下图所示:
服务
我目前创建服务都是使用的 Topshelf,使用起来也非常简单,这里不过多介绍。官网:https://topshelf-project.com/index.html。
Topshelf 创建的服务想要实现开机自启,只需要设置 StartAutomatically()即可,官网链接:
https://topshelf.readthedocs.io/en/latest/configuration/config_api.html#service-start-modes
总结
推荐使用启动文件夹(当前用户)或注册表(当前用户)的方式,简单且无需管理员权限。