新聞速報

        

2018年5月25日 星期五

run as administrator

1.C#程序以管理員權限運行
2. 指定使用者名稱來執行外部程式

C#程序以管理員權限運行
在Vista 和 Windows 7 及更新版本的操作系統,增加了 UAC(用戶賬戶控制) 的安全機制,如果 UAC 被打開,用戶即使以管理員權限登錄,其應用程序默認情況下也無法對系統目錄、系統註冊表等可能影響系統正常運行的設置進行寫操作。這個機制大大增強了系統 的安全性,但對應用程序開發者來說,我們不能強迫用戶去關閉UAC,但有時我們開發的應用程序又需要以 Administrator 的方式運行,如何實現這樣的功能呢?

下面演示 C# 程序如何實現提示用戶以管理員權限運行。
本例以WinForm程序演示,新建一項目生成後進行相應修改:
方法一:通過 System.Diagnostics.Process.Start() 方式啟動:
實現方法: 修改默認生成的Program文件,修改後的代碼如下:
由於已經在代碼上做了註釋,所以不再詳細說明;
static class Program
    {
        [STAThread]
        static void Main()
        {           
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            /**
             * 當前用戶是管理員的時候,直接啟動應用程序
             * 如果不是管理員,則使用啟動對象啟動程序,以確保使用管理員身份運行
             */
            //獲得當前登錄的Windows用戶標示
            System.Security.Principal.WindowsIdentity identity = System.Security.Principal.WindowsIdentity.GetCurrent();
            System.Security.Principal.WindowsPrincipal principal = new System.Security.Principal.WindowsPrincipal(identity);
            //判斷當前登錄用戶是否為管理員
            if (principal.IsInRole(System.Security.Principal.WindowsBuiltInRole.Administrator))
            {
                //如果是管理員,則直接運行
                Application.Run(new Form1());
            }
            else
            {
                //創建啟動對象
                System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
                startInfo.UseShellExecute = true;
                startInfo.WorkingDirectory = Environment.CurrentDirectory;
                startInfo.FileName = Application.ExecutablePath;
                //設置啟動動作,確保以管理員身份運行
                startInfo.Verb = "runas";
                try
                {
                    System.Diagnostics.Process.Start(startInfo);
                }
                catch
                {
                    return;
                }
                //退出
                Application.Exit();
            }
        }
    }


指定使用者名稱來執行外部程式 
通常由我們寫好的程式來執行其它程式時,該程式的使用者名稱會跟我們的程式是同一個。但若是想要用不同的使用者名稱來執行的話,就得要在使用 Process.start() 時特別指定使用者名稱及密碼。



再來就是動作手程式的時間哩:但未了方便起見,所以筆者先匯入 System.DiagnosticsSystem.SecuritySystem.ComponentModel 等命名空間


// 匯入 System.Diagnostics、System.Security 及 System.ComponentModel
using System.Diagnostics;
using System.Security;
using System.ComponentModel;


還記得在利用 Process 來執行其它外部程式有提到可以利用 Process.start(FileName, ar) 的方法來執行外部程式。那麼現在也是利用同樣方法,但我們需要提供更多的參數,例如:使用者名稱及密碼


// 程式的名稱, 使用者名稱, 密碼及網域
Process.Start(fileName, userName, password, domain);


且使用者密碼型態是 SecureString 類別,所以筆者多寫一個轉把字串轉換成 SecureString 類別的方法





// 把 string 轉成 SecureString 類別
private SecureString ConvertStringToSecureString(string pwd) 
{
    SecureString passWord = new SecureString();
    foreach (char c in pwd)  
    {
      passWord.AppendChar(c);
     }
 
    return passWord;
}


準備好之後,先寫利用 Administrator 使用者名稱的功能:












private void administratorBtn_Click(object sender, System.EventArgs e) {
 // 要執行的檔案名稱(必要時需要加讓路徑)
 string fileName = "notepad.exe";
 // 指定要執行程式的使用者名稱
 string userName = "administrator";
 // 指定要執行程式的使用者名稱密碼,但需要是 SecureString 類別
 SecureString password = ConvertStringToSecureString("administrator password");
 
 try  
 {
   // 執行程式
   Process.Start(fileName, userName, password, null);
 }  
 catch(Win32Exception win32Exception) 
 {
    // 如果使用者名稱或密碼不正確時會丟出 Win32Exception
    MessageBox.Show("不正確的使用者帳號或密碼!", "錯誤");
 }
}


只要在使用 start() 時特別指定使用者名稱跟密碼就能用該使用者的權限來執行了。Process 類別的用法可以參考:利用 Process 來執行其它外部程式

既然能寫用 Administrator 的話,那麼要寫下一個就是只要改使用者名稱跟密碼就可以了


private void abgne_twBtn_Click(object sender, System.EventArgs e)  
{
   // 要執行的檔案名稱(必要時需要加讓路徑)
   string fileName = "notepad.exe";
   // 指定要執行程式的使用者名稱
   string userName = "abgne.tw";
   // 指定要執行程式的使用者名稱密碼,但需要是 SecureString 類別
   SecureString password = ConvertStringToSecureString("abgne.tw password");
 
   try  
   {
     // 執行程式
     Process.Start(fileName, userName, password, null);
   }  
   catch(Win32Exception win32Exception) 
   {
     // 如果使用者名稱或密碼不正確時會丟出 Win32Exception
     MessageBox.Show("不正確的使用者帳號或密碼!", "錯誤");
   }
}
 

沒有留言:

張貼留言