[Winform]安装在C盘,无操作权限的一个解决办法
摘要
在對(duì)winform打包,進(jìn)行安裝的時(shí)候,一般會(huì)采用默認(rèn)的安裝路徑,默認(rèn)安裝在C:\Program Files\xx或者C:\Program Files(x86)目錄下,但windows有一種安全策略,默認(rèn)是不允許操作c盤(pán)文件或者文件夾的。
解決辦法
在軟件發(fā)布的時(shí)候,一般會(huì)對(duì)軟件exe進(jìn)行簽名的,使其發(fā)布者顯示為某某公司,這里建議另建一個(gè)軟件啟動(dòng)程序,對(duì)啟動(dòng)程序進(jìn)行簽名。這樣你的軟件如果更新,就不需要反復(fù)的對(duì)軟件進(jìn)行簽名了。
1、啟動(dòng)程序可以,在配置文件中,設(shè)置啟動(dòng)的exe名稱(chēng)。可以多個(gè)軟件公用一個(gè)啟動(dòng)程序,而改變啟動(dòng)程序名稱(chēng)對(duì)簽名是沒(méi)有影響的。
2、可以在啟動(dòng)程序中,對(duì)軟件目錄進(jìn)行權(quán)限驗(yàn)證。如果沒(méi)有權(quán)限,可以讓其彈出UAC窗口,以管理員身份運(yùn)行,并在主程序中,對(duì)軟件所在目錄進(jìn)行授權(quán)操作。
核心代碼
啟動(dòng)程序
class Program{static string _exeName = ConfigurationManager.AppSettings["exeName"];static string _exeDir = AppDomain.CurrentDomain.BaseDirectory;static string _startExePath = Path.Combine(_exeDir, _exeName);static EventLog log = new EventLog() { Source = Path.GetFileNameWithoutExtension(_exeName) };static void Main(string[] args){try{if (string.IsNullOrEmpty(_exeName)){log.WriteEntry("no set exe name", EventLogEntryType.Error);}else{if (!IsAdmin()){//是否有完全控制權(quán)限if (CheckFolderPermissions(_exeDir, FileSystemRights.FullControl)){//運(yùn)行主進(jìn)程,不彈出UAC窗口RunAsAdmin(false);}else{//彈出UAC窗口,以管理員身份運(yùn)行程序,并在主程序中,進(jìn)行文件夾授權(quán)RunAsAdmin(true);}}else{//運(yùn)行主進(jìn)程,不彈出UAC窗口RunAsAdmin(false);}}}catch (Exception ex){log.WriteEntry(ex.Message, EventLogEntryType.Error);}}/// <summary>/// 檢查文件夾權(quán)限/// </summary>/// <param name="dirPath"></param>/// <param name="accessType"></param>/// <returns></returns>public static bool CheckFolderPermissions(string dirPath, FileSystemRights accessType){bool havePermission = false;try{AuthorizationRuleCollection collection = Directory.GetAccessControl(dirPath).GetAccessRules(true, true, typeof(System.Security.Principal.NTAccount));foreach (FileSystemAccessRule rule in collection){if ((rule.FileSystemRights & accessType) > 0){havePermission=true;break;}}}catch{havePermission = false;}return havePermission;}/// <summary>/// 以管理員身份運(yùn)行,彈出UAC控制窗口/// </summary>/// <param name="isRunAsAdmin">是否彈出uac控制</param>private static void RunAsAdmin(bool isRunAsAdmin){//創(chuàng)建啟動(dòng)對(duì)象 System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();//設(shè)置運(yùn)行文件 startInfo.FileName = _startExePath;if (isRunAsAdmin){//設(shè)置啟動(dòng)動(dòng)作,確保以管理員身份運(yùn)行 startInfo.Verb = "runas";}if (File.Exists(_startExePath)){//如果不是管理員,則啟動(dòng)UAC System.Diagnostics.Process.Start(startInfo);}else{log.WriteEntry("not find the appication to run", EventLogEntryType.Error);}}/// <summary>/// 是否是管理員/// </summary>/// <returns></returns>static bool IsAdmin(){try{System.Security.Principal.WindowsIdentity identity = System.Security.Principal.WindowsIdentity.GetCurrent();System.Security.Principal.WindowsPrincipal principal = new System.Security.Principal.WindowsPrincipal(identity);return principal.IsInRole(System.Security.Principal.WindowsBuiltInRole.Administrator);}catch{return false;}}}
主程序在Main函數(shù)中進(jìn)行授權(quán)
SetAccess("Users", StaticParameter.ExeDir); /// <summary>/// 為指定用戶(hù)組,授權(quán)目錄指定完全訪問(wèn)權(quán)限/// </summary>/// <param name="user">用戶(hù)組,如Users</param>/// <param name="folder">實(shí)際的目錄</param>/// <returns></returns>public static bool SetAccess(string user, string folder){//定義為完全控制的權(quán)限const FileSystemRights Rights = FileSystemRights.FullControl;//添加訪問(wèn)規(guī)則到實(shí)際目錄var AccessRule = new FileSystemAccessRule(user, Rights,InheritanceFlags.None,PropagationFlags.NoPropagateInherit,AccessControlType.Allow);var Info = new DirectoryInfo(folder);var Security = Info.GetAccessControl(AccessControlSections.Access);bool Result;Security.ModifyAccessRule(AccessControlModification.Set, AccessRule, out Result);if (!Result) return false;//總是允許再目錄上進(jìn)行對(duì)象繼承const InheritanceFlags iFlags = InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit;//為繼承關(guān)系添加訪問(wèn)規(guī)則AccessRule = new FileSystemAccessRule(user, Rights,iFlags,PropagationFlags.InheritOnly,AccessControlType.Allow);Security.ModifyAccessRule(AccessControlModification.Add, AccessRule, out Result);if (!Result) return false;Info.SetAccessControl(Security);return true;}在授權(quán)的時(shí)候,需要保證是管理員身份運(yùn)行的。所在在啟動(dòng)程序中,可以先判斷目錄的權(quán)限,如果還未授權(quán),則彈出UAC窗口,使其以管理員身份運(yùn)行,首次運(yùn)行授權(quán),之后運(yùn)行就可以跳過(guò)這個(gè)過(guò)程。
總結(jié)
文件及文件夾提權(quán),在C/s中是經(jīng)常遇到的一個(gè)問(wèn)題。比如,如果你沒(méi)有讀寫(xiě)權(quán)限,如果操作sqlite就會(huì)提示沒(méi)權(quán)限操作數(shù)據(jù)庫(kù)的bug。
參考
http://www.cnblogs.com/wuhuacong/p/5645172.html
轉(zhuǎn)載于:https://www.cnblogs.com/wolf-sun/p/7325205.html
總結(jié)
以上是生活随笔為你收集整理的[Winform]安装在C盘,无操作权限的一个解决办法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 解决四个字节的字符无法存入数据库
- 下一篇: 京东宣布收购拇指阅读,具体金额未披露