天天看點

巧妙地利用程序分離來設定程式開機自動啟動!(附源碼)

如果僅僅為了一個很少用到的功能就将程式要求為以管理者身份運作,就太不優雅和太浪費了,本文介紹一種程序分離的方式來巧妙地達到目的!

  在GG(高仿QQ)最早的版本中,我就加入了開機自動啟動的功能,是通過操作系統資料庫來實作的,但是操作系統資料庫需要管理者權限,這樣,就表示必須以管理者的身份來運作GG用戶端。這對某些使用者來說可能接受不了,因為以這麼高的權限來運作一個程式,使用者會覺得風險較大。而就從GG的角度來說,也隻有在設定或取消開機啟動才需要這個權限,而一開始就以管理者身份運作GG,就有點太誇張和浪費了。

一.方案進化

  我開始想到的解決方案是,仍然以普通使用者的身份啟動GG,當需要操作系統資料庫時,再提升至管理者權限。後來通過查資料了解到:

(1)無法單獨提升某個線程的運作權限,運作權限是與程序綁定了。

(2)若要提升程序的權限,必須在程序啟動時就設定。

  這意味着要實作我的方案,必須在GG設定或取消開機啟動時,重新開機GG程序。這也太不優雅了。繼續想辦法,最後讓我想到了一個巧妙的方案。思路如下:

(1)将GG中設定或取消開機啟動的功能(即需要管理者權限的部分),做成一個單獨的控制台程式AutoStart.exe,并且将其運作權限配置為管理者。

(2)将AutoStart.exe放到與GG.exe的運作目錄。

(3)GG實作開機啟動功能的方法就是啟動AutoStart.exe程序,并通過啟動參數來傳遞相關資訊給AutoStart.exe程序。

二.方案實作

1.AutoStart.exe

  AutoStart.exe是一個控制台程式,我将其實作為一個可複用的應用程式,大家可以直接從文末下載下傳複用。其源碼相當簡單,如下所示:

     /// <summary>
        /// 第一個參數為exe的名稱,第二個參數為bool值,表示是否自動啟動
        /// </summary>        
        static void Main(string[] args)
        {
            try
            {
                bool autoStart = bool.Parse(args[1]);
                Console.WriteLine(string.Format("正在{0}自動啟動 {1} . . .", autoStart ? "設定" : "取消" ,args[0]) );                
                //操作系統資料庫,需要使用管理者身份啟動程式。
                RunWhenStart_usingReg(autoStart, args[0], AppDomain.CurrentDomain.BaseDirectory + args[0]);
                Console.WriteLine("");
                Console.WriteLine("操作完成! 按任意鍵退出 . . .");               
                Console.ReadLine();
            }
            catch(Exception ee)
            {
                Console.WriteLine("操作時發生異常:" + ee.Message + " 按任意鍵退出 . . .");               
                Console.ReadLine();
            }
        }

        #region 開機自動啟動
        /// <summary> 
        /// 開機自動啟動,使用系統資料庫 
        /// </summary> 
        /// <param name=\"Started\">是否開機自動啟動</param> 
        /// <param name=\"name\">取一個唯一的系統資料庫Key名稱</param> 
        /// <param name=\"path\">啟動程式的完整路徑</param> 
        public static void RunWhenStart_usingReg(bool started, string name, string path)
        {
            RegistryKey HKLM = Registry.LocalMachine;
            try
            {
                RegistryKey run = HKLM.CreateSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\\");
                if (started)
                {
                    run.SetValue(name, path);
                }
                else
                {
                    object val = run.GetValue(name);
                    if (val != null)
                    {
                        run.DeleteValue(name);
                    }
                }
            }
            finally
            {
                HKLM.Close();
            }
        }
        #endregion            

  如果不知道如何将AutoStart.exe配置為以管理者身份啟動,可以參考這篇文章。

2.在GG中調用AutoStart.exe

  當使用者都選上或去掉勾選"開機自動啟動"時,程式執行如下操作:

if (autoStartChanged)
    {
        string args = string.Format("{0} {1}", "GG.exe", autoStart? "true":"false");
        Process.Start(AppDomain.CurrentDomain.BaseDirectory + "AutoStart.exe", args);
    }      

  運作效果截圖:

  

巧妙地利用程式分離來設定程式開機自動啟動!(附源碼)

三.下載下傳

1.AutoStart 可執行程式

2.AutoStart 源碼

PS:QQ的自動啟動是怎麼實作的了?它似乎不需要管理者權限,有知道的朋友拜托留言告訴一下啊,謝謝! 

大家有什麼問題和建議,可以留言,也可以發送email到我郵箱:[email protected]。 

如果你覺得還不錯,請粉我,順便再頂一下啊