最近在做一個項目(平台 .net 4.0 winform)的時候,客戶要求軟件能提供開機啟動的設置選項
開始的時候,實現方法如下:
public class Boot { //寫入注冊表 public static void bootFromBoot(string ExeName, string ExePath) { RegistryKey rKey = Registry.LocalMachine; RegistryKey autoRun = rKey.CreateSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run"); 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(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run"); 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" + "\r\n"; bat += "cacls.exe \"%SystemDrive%\\System Volume Information\" >nul 2>nul" + "\r\n"; bat += "if %errorlevel%==0 goto Admin" + "\r\n"; bat += "echo request Administrator" + "\r\n"; bat += "if exist \"%temp%\\getadmin.vbs\" del /f /q \"%temp%\\getadmin.vbs\"" + "\r\n"; bat += "echo Set RequestUAC = CreateObject^(\"Shell.Application\"^)>\"%temp%\\getadmin.vbs\"" + "\r\n"; bat += "echo RequestUAC.ShellExecute \"%~s0\",\"\",\"\",\"runas\",1 >>\"%temp%\\getadmin.vbs\"" + "\r\n"; bat += "echo WScript.Quit >>\"%temp%\\getadmin.vbs\"" + "\r\n"; bat += "\"%temp%\\getadmin.vbs\" /f" + "\r\n"; bat += "if exist \"%temp%\\getadmin.vbs\" del /f /q \"%temp%\\getadmin.vbs\"" + "\r\n"; bat += "exit" + "\r\n"; bat += ":Admin" + "\r\n"; bat += "echo delete reg" + "\r\n"; bat += "reg delete \"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\" /v " + key + " /f" + "\r\n"; //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" + "\r\n"; bat += "cacls.exe \"%SystemDrive%\\System Volume Information\" >nul 2>nul" + "\r\n"; bat += "if %errorlevel%==0 goto Admin" + "\r\n"; bat += "echo request Administrator" + "\r\n"; bat += "if exist \"%temp%\\getadmin.vbs\" del /f /q \"%temp%\\getadmin.vbs\"" + "\r\n"; bat += "echo Set RequestUAC = CreateObject^(\"Shell.Application\"^)>\"%temp%\\getadmin.vbs\"" + "\r\n"; bat += "echo RequestUAC.ShellExecute \"%~s0\",\"\",\"\",\"runas\",1 >>\"%temp%\\getadmin.vbs\"" + "\r\n"; bat += "echo WScript.Quit >>\"%temp%\\getadmin.vbs\"" + "\r\n"; bat += "\"%temp%\\getadmin.vbs\" /f" + "\r\n"; bat += "if exist \"%temp%\\getadmin.vbs\" del /f /q \"%temp%\\getadmin.vbs\"" + "\r\n"; bat += "exit" + "\r\n"; bat += ":Admin" + "\r\n"; bat += "echo add reg" + "\r\n"; bat += "reg add \"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\" /v " + key + " /d " + "\"" + exeFullPath + "\"" + " /f" + "\r\n"; //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); }