[Winform]安裝在C盤,無操作權限的一個解決辦法


摘要

在對winform打包,進行安裝的時候,一般會采用默認的安裝路徑,默認安裝在C:\Program Files\xx或者C:\Program Files(x86)目錄下,但windows有一種安全策略,默認是不允許操作c盤文件或者文件夾的。

解決辦法

在軟件發布的時候,一般會對軟件exe進行簽名的,使其發布者顯示為某某公司,這里建議另建一個軟件啟動程序,對啟動程序進行簽名。這樣你的軟件如果更新,就不需要反復的對軟件進行簽名了。

1、啟動程序可以,在配置文件中,設置啟動的exe名稱。可以多個軟件公用一個啟動程序,而改變啟動程序名稱對簽名是沒有影響的。

2、可以在啟動程序中,對軟件目錄進行權限驗證。如果沒有權限,可以讓其彈出UAC窗口,以管理員身份運行,並在主程序中,對軟件所在目錄進行授權操作。

核心代碼

啟動程序

  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())
                    {
                        //是否有完全控制權限
                        if (CheckFolderPermissions(_exeDir, FileSystemRights.FullControl))
                        {
                            //運行主進程,不彈出UAC窗口
                            RunAsAdmin(false);
                        }
                        else
                        {
                            //彈出UAC窗口,以管理員身份運行程序,並在主程序中,進行文件夾授權
                            RunAsAdmin(true);
                        }
                    }
                    else
                    {
                        //運行主進程,不彈出UAC窗口
                        RunAsAdmin(false);
                    }

                }
            }
            catch (Exception ex)
            {
                log.WriteEntry(ex.Message, EventLogEntryType.Error);
            }

        }
        /// <summary>
        /// 檢查文件夾權限
        /// </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> /// 以管理員身份運行,彈出UAC控制窗口 /// </summary> /// <param name="isRunAsAdmin">是否彈出uac控制</param> private static void RunAsAdmin(bool isRunAsAdmin) { //創建啟動對象 System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo(); //設置運行文件 startInfo.FileName = _startExePath; if (isRunAsAdmin) { //設置啟動動作,確保以管理員身份運行 startInfo.Verb = "runas"; } if (File.Exists(_startExePath)) { //如果不是管理員,則啟動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函數中進行授權

SetAccess("Users", StaticParameter.ExeDir);
        /// <summary>
        /// 為指定用戶組,授權目錄指定完全訪問權限
        /// </summary>
        /// <param name="user">用戶組,如Users</param>
        /// <param name="folder">實際的目錄</param>
        /// <returns></returns>
        public static bool SetAccess(string user, string folder)
        {
            //定義為完全控制的權限
            const FileSystemRights Rights = FileSystemRights.FullControl;

            //添加訪問規則到實際目錄
            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;

            //總是允許再目錄上進行對象繼承
            const InheritanceFlags iFlags = InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit;

            //為繼承關系添加訪問規則
            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;
        }

在授權的時候,需要保證是管理員身份運行的。所在在啟動程序中,可以先判斷目錄的權限,如果還未授權,則彈出UAC窗口,使其以管理員身份運行,首次運行授權,之后運行就可以跳過這個過程。

總結

文件及文件夾提權,在C/s中是經常遇到的一個問題。比如,如果你沒有讀寫權限,如果操作sqlite就會提示沒權限操作數據庫的bug。

參考

http://www.cnblogs.com/wuhuacong/p/5645172.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM