最近在做一个项目(平台 .net 4.0 winform)的时候,客户要求软件能提供开机启动的设置选项
开始的时候,实现方法如下:
public class Boot { //写入注册表 public static void bootFromBoot(string ExeName, string ExePath) { RegistryKey rKey = Registry.LocalMachine; RegistryKey autoRun = rKey.CreateSubKey(@"SOFTWAREMicrosoftWindowsCurrentVersionRun"); try { autoRun.SetValue(ExeName, ExePath); } catch (System.Exception ex) { throw ex; } } //删除注册表 public static void deleteFromBoot(string ExeName, string ExePath) { RegistryKey rKey = Registry.LocalMachine; RegistryKey autoRun = rKey.CreateSubKey(@"SOFTWAREMicrosoftWindowsCurrentVersionRun"); try { //autoRun.DeleteValue(ExePath); if (autoRun.GetValue(ExeName) != null) autoRun.DeleteValue(ExeName); } catch (System.Exception ex) { throw ex; } }
但是有个问题,应用程序没有管理员权限的时候,写入注册表会失败,在winform的项目属性里面打开了获取管理员权限
这回成功了,可以应用程序在win10系统上运行的时候,无法将桌面快捷方式拖进应用程序,报错,
找到原因是:取消管理员权限的时候,在win10上就能正常运行了,但是开机启动写入注册表就不行了,
脑袋瓜还是好使的(感谢上帝赐给的智慧),想到用windows的批处理文件进行注册表写入
#region bat批处理 public static void CreateRegDeleteBat(string file_path, string key) { if (System.IO.File.Exists(file_path)) { System.IO.File.Delete(file_path); } string bat = "@echo off" + " "; bat += "cacls.exe "%SystemDrive%\System Volume Information" >nul 2>nul" + " "; bat += "if %errorlevel%==0 goto Admin" + " "; bat += "echo request Administrator" + " "; bat += "if exist "%temp%\getadmin.vbs" del /f /q "%temp%\getadmin.vbs"" + " "; bat += "echo Set RequestUAC = CreateObject^("Shell.Application"^)>"%temp%\getadmin.vbs"" + " "; bat += "echo RequestUAC.ShellExecute "%~s0","","","runas",1 >>"%temp%\getadmin.vbs"" + " "; bat += "echo WScript.Quit >>"%temp%\getadmin.vbs"" + " "; bat += ""%temp%\getadmin.vbs" /f" + " "; bat += "if exist "%temp%\getadmin.vbs" del /f /q "%temp%\getadmin.vbs"" + " "; bat += "exit" + " "; bat += ":Admin" + " "; bat += "echo delete reg" + " "; bat += "reg delete "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" /v " + key + " /f" + " "; //bat += "PAUSE"; System.IO.File.WriteAllText(file_path, bat, Encoding.Default); } public static void CreateRegAddBat(string file_path, string key, string exeFullPath) { if (System.IO.File.Exists(file_path)) { System.IO.File.Delete(file_path); } string bat = "@echo off" + " "; bat += "cacls.exe "%SystemDrive%\System Volume Information" >nul 2>nul" + " "; bat += "if %errorlevel%==0 goto Admin" + " "; bat += "echo request Administrator" + " "; bat += "if exist "%temp%\getadmin.vbs" del /f /q "%temp%\getadmin.vbs"" + " "; bat += "echo Set RequestUAC = CreateObject^("Shell.Application"^)>"%temp%\getadmin.vbs"" + " "; bat += "echo RequestUAC.ShellExecute "%~s0","","","runas",1 >>"%temp%\getadmin.vbs"" + " "; bat += "echo WScript.Quit >>"%temp%\getadmin.vbs"" + " "; bat += ""%temp%\getadmin.vbs" /f" + " "; bat += "if exist "%temp%\getadmin.vbs" del /f /q "%temp%\getadmin.vbs"" + " "; bat += "exit" + " "; bat += ":Admin" + " "; bat += "echo add reg" + " "; bat += "reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" /v " + key + " /d " + """ + exeFullPath + """ + " /f" + " "; //bat += "PAUSE"; System.IO.File.WriteAllText(file_path, bat, Encoding.Default); } public static void RunBATfile(string file_path, string file_name) { Process pro = new Process(); pro.StartInfo.FileName = file_name; pro.StartInfo.WorkingDirectory = file_path; pro.StartInfo.CreateNoWindow = true; pro.Start(); pro.WaitForExit(); } #endregion
使用的时候这样:
private void reg_add() { string exe_path = Application.StartupPath; string file_name = "add_reg.bat"; string full_path = exe_path + "\" + file_name; string IconSyncPath = Application.ExecutablePath; FileHelper.CreateRegAddBat(full_path, "IconSync", IconSyncPath); FileHelper.RunBATfile(exe_path, file_name); } private void reg_delete() { string exe_path = Application.StartupPath; string file_name = "delete_reg.bat"; string full_path = exe_path + "\" + file_name; FileHelper.CreateRegDeleteBat(full_path, "IconSync"); FileHelper.RunBATfile(exe_path, file_name); }