unity应用开机自启
来源:互联网 发布:淘宝店铺添加到桌面 编辑:程序博客网 时间:2024/06/13 00:21
最近有一个项目需要设置开机自启动,没有预先为程序设定这个功能,所以部署的时候每次都要生成快捷方式,然后找自启动文件夹,搞得非常崩溃。所以决定填上这个坑,写了一段unity应用通用的开启和关闭开机自启的代码。
更新历史
- 2017.10.15:完成初稿
写在前面
经过一晚上的研究和分析,发现设置开机自启动主要有两种主流方式和一种非主流方式,这几个方式基本能满足需求,分别是:
1. 开始菜单启动(最常用,不需要管理员权限)
2. 注册表启动项(需要管理员权限)
3. Windows计划任务(需要管理员权限,unity中使用有异常)
以下代码都是即拿即用,只需绑定Button和Text即可。
开始菜单启动
开始菜单启动大概是我们最常用的一种设置开机自启的方法,具体用程序来实现也是很简单的,主要有两步:
1. 创建快捷方式并关联程序
2. 将快捷方式存到“开始”菜单的“启动”目录
代码如下:
using System;using System.IO;using UnityEngine;using UnityEngine.UI;using IWshRuntimeLibrary;public class StartMenu : MonoBehaviour { public Button setupStartupButton; public Button cancelStartupButton; public Text hintText; private static string ShortcutName = "test.lnk"; private void OnEnable() { isStartup(); setupStartupButton.onClick.AddListener(OnSetupStartupButtonClick); cancelStartupButton.onClick.AddListener(OnCancelStartupButtonClick); } private void OnDisable() { setupStartupButton.onClick.RemoveListener(OnSetupStartupButtonClick); cancelStartupButton.onClick.RemoveListener(OnCancelStartupButtonClick); } private void OnSetupStartupButtonClick() { CreateShortcut(Environment.GetFolderPath(Environment.SpecialFolder.Startup), ShortcutName, System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName); isStartup(); } private void OnCancelStartupButtonClick() { if (System.IO.File.Exists(Environment.GetFolderPath(Environment.SpecialFolder.Startup) + "\\" + ShortcutName)) System.IO.File.Delete(Environment.GetFolderPath(Environment.SpecialFolder.Startup) + "\\" + ShortcutName); isStartup(); } private void isStartup() { if (System.IO.File.Exists(Environment.GetFolderPath(Environment.SpecialFolder.Startup) + "\\" + ShortcutName)) hintText.text = "应用已开机自启"; else hintText.text = "应用非开机自启"; } public static bool CreateShortcut(string direstory,string shortcurName,string targetPath,string description = null,string iconLocation = null) { try { if(!Directory.Exists(direstory)) { Directory.CreateDirectory(direstory); } // 添加引用com中搜索Windows Script Host Object Model, 如果在unity中使用则需下载 Interop.IWshRuntimeLibrary.dll 并放到代码同一文件夹 string shortscurPath = Path.Combine(direstory, string.Format("{0}", shortcurName)); IWshRuntimeLibrary.WshShell shell = new IWshRuntimeLibrary.WshShell(); IWshRuntimeLibrary.IWshShortcut shortcut = (IWshRuntimeLibrary.IWshShortcut)shell.CreateShortcut(shortscurPath); // 创建快捷方式对象 shortcut.TargetPath = targetPath; // 指定目标路径 shortcut.WorkingDirectory = Path.GetDirectoryName(targetPath); //设置起始位置 shortcut.WindowStyle = 1; // 设置运行方式,默认为常规窗口 shortcut.Description = description; // 设置备注 shortcut.IconLocation = string.IsNullOrEmpty(iconLocation) ? targetPath : iconLocation; //设置图标路径 shortcut.Save(); // 保存快捷方式 return true; } catch { } return false; }}
使用开始菜单自启是非常稳的一种方法,不需要有管理员权限,但是unity中使用需要添加引用,并下载 Interop.IWshRuntimeLibrary.dll 程序集放到与本代码同一文件夹。
注册表开机启动项
这个相信是大部分同学使用的情况,简单易懂隐蔽(只是感觉很隐蔽,但是 msconfig 立马暴露),代码很简单,将启动的项目名称、文件位置添加到启动项即可。
using Microsoft.Win32;using System.Collections;using System.Collections.Generic;using UnityEngine;using UnityEngine.UI;using System;public class Regeditkey : MonoBehaviour { public Button setupStartupButton; public Button cancelStartupButton; public Text hintText; private void OnEnable() { string path = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName; //regeditkey(); setupStartupButton.onClick.AddListener(OnSetupStartupButtonClick); cancelStartupButton.onClick.AddListener(OnCancelStartupButtonClick); } private void OnDisable() { setupStartupButton.onClick.RemoveListener(OnSetupStartupButtonClick); cancelStartupButton.onClick.RemoveListener(OnCancelStartupButtonClick); } private void OnSetupStartupButtonClick() { // 提示,需要更改注册表 try { string path = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName; RegistryKey rgkRun = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true); if(rgkRun == null) { rgkRun = Registry.LocalMachine.CreateSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run"); } rgkRun.SetValue("dhstest", path); // 名字请自行设置 } catch { Debug.Log(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName); } finally { regeditkey(); } } private void OnCancelStartupButtonClick() { // 提示,需要更改注册表 try { string path = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName; RegistryKey rgkRun = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true); if (rgkRun == null) { rgkRun = Registry.LocalMachine.CreateSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run"); } rgkRun.DeleteValue("dhstest", false); } catch { Debug.Log("error"); } finally { regeditkey(); } } private void regeditkey() { RegistryKey rgkRun = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run",true); if(rgkRun.GetValue("dhstest") == null) { hintText.text = "自启动为关闭"; } else { hintText.text = "自启动为打开"; } }}
此方法在unity中使用也稳定有效,不需要下载程序集,但是需要以管理员权限运行程序才能修改注册表。
Windows 计划任务方式启动
计划任务表有很多人都不熟悉,但是它确实有很多妙用。但是在把代码转成unity应用后发现unity开发的应用中无法使用,初步认定的原因是,Interop.TaskScheduler.dll 程序集需要设置嵌入互操作类型为 false 但是unity 开发的应用中应用的程序集并没有这个选项,所以用 unity 大概不能使用Windows计划任务管理器。
为了验证计划任务管理器是否有效,我在wpf应用上测试了一下,wpf的引用是有设置嵌入互操作类型选项的,将其改为false即可正常引用 Interop.TaskScheduler 程序集。
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows;using System.Windows.Controls;using System.Windows.Data;using System.Windows.Documents;using System.Windows.Input;using System.Windows.Media;using System.Windows.Media.Imaging;using System.Windows.Navigation;using System.Windows.Shapes;using TaskScheduler;namespace Task{ /// <summary> /// MainWindow.xaml 的交互逻辑 /// </summary> public partial class MainWindow : Window { private string TaskName = "test"; public MainWindow() { InitializeComponent(); isStartup(); } private void OnSetupStartupButtonClick(object sender, RoutedEventArgs e) { if (!HaveTaskScheduler(TaskName)) CreateTaskScheduler(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName, "xtw", "Set startup"); else GetTaskScheduler(TaskName).Enabled = true; isStartup(); } private void OnCancelStartupButtonClick(object sender, RoutedEventArgs e) { if (HaveTaskScheduler(TaskName)) GetTaskScheduler(TaskName).Enabled = false; isStartup(); } private bool HaveTaskScheduler(string name) { IRegisteredTask task = GetTaskScheduler(name); if (task == null) return false; else return true; } private void isStartup() { if (HaveTaskScheduler(TaskName) && GetTaskScheduler(TaskName).Enabled) text.Content = "应用已开机自启"; // 此text是Windows 组件Label else text.Content = "应用非开机自启"; } private static IRegisteredTask GetTaskScheduler(string name) { // 新建任务 TaskSchedulerClass scheduler = new TaskSchedulerClass(); // 连接 scheduler.Connect(null, null, null, null); // 获取创建任务的目录 ITaskFolder folder = scheduler.GetFolder("\\"); IRegisteredTask task; try { task = folder.GetTask(name); } catch { return null; } return task; } private void CreateTaskScheduler(string file, string author, string desc) { // 新建任务 TaskSchedulerClass scheduler = new TaskSchedulerClass(); // 连接 scheduler.Connect(null, null, null, null); // 获取创建任务的目录 ITaskFolder folder = scheduler.GetFolder("\\"); // 设置参数 ITaskDefinition task = scheduler.NewTask(0); task.RegistrationInfo.Author = author; // 创建者 task.RegistrationInfo.Description = desc; //描述 // 设置触发机制 (此处是 登录后) task.Triggers.Create(_TASK_TRIGGER_TYPE2.TASK_TRIGGER_LOGON); // 设置动作 (此处为 exe运行程序) IExecAction action = (IExecAction)task.Actions.Create(_TASK_ACTION_TYPE.TASK_ACTION_EXEC); action.Path = file; //设置文件目录 //task.Settings.ExecutionTimeLimit = "PTOS"; //运行任务时间超时停止任务吗?PTOS不开启超时 task.Settings.DisallowStartIfOnBatteries = false; //只在交流电下才执行 task.Settings.RunOnlyIfIdle = false; // 仅当计算机空闲下才执行 IRegisteredTask regTask = folder.RegisterTaskDefinition(TaskName, task, // 此处需要设置任务的名称(name) (int)_TASK_CREATION.TASK_CREATE, null, // user null,//passward _TASK_LOGON_TYPE.TASK_LOGON_INTERACTIVE_TOKEN, ""); IRunningTask runTask = regTask.Run(null); } }}
总结
对于开发一般应用来说,开始菜单启动是最简单、有效的方法。对于开发 unity 应用来说,这也不失为是一种好方法。
参考链接
- C# 将程序添加开机启动的三种方式
- Unity设置自启动项目
- 动态加载dll程序集
- C#操作计划任务
- unity应用开机自启
- 应用开机自启
- 应用开机自启
- 开机自启应用
- Android应用开机自启
- Android应用开机自启
- Android开机自启APK应用
- 应用开机自启问题排查
- 应用开机自启动
- Android 开机自启动应用
- Android 开机自启动应用
- Android 开机自启动应用
- Android 开机自启动应用
- Android 开机自启动应用
- Android开机自启动应用
- Android 开机自启动应用
- Android开机自启动应用
- Android 开机自启动应用
- MyBatis学习资源
- ReactiveCocoa 基本工作流程整理
- 使用Helm charts在Kubernetes 1.4 MongoDB上部署
- 扩展KMP(模式串与文本串的最长公共前缀)
- matlab 环境 word 和 excel 文件操作
- unity应用开机自启
- BigDecimal
- 谷歌浏览器安装 jsonview 插件
- 循环累加远算
- NOIP2017旅游(过节)总结
- Java线程安全问题——同步和死锁
- 今天项目报错: No operations allowed after connection closed
- Window从linxu服务器上传与下载文件
- 小白的廖雪峰JS教程学习笔记要点---数据类型和变量