码迷,mamicode.com
首页 > Windows程序 > 详细

[Winform]安装在C盘,无操作权限的一个解决办法

时间:2017-08-09 15:29:41      阅读:1892      评论:0      收藏:0      [点我收藏+]

标签:als   主程序   www.   安全   null   eof   source   void   上进   

摘要

在对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 = true;
            try
            {
                AuthorizationRuleCollection collection = Directory.
                                          GetAccessControl(dirPath)
                                          .GetAccessRules(true, true, typeof(System.Security.Principal.NTAccount));
                foreach (FileSystemAccessRule rule in collection)
                {
                    if ((rule.FileSystemRights & accessType) > 0)
                    {
                        return havePermission;
                    }
                }

            }
            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

[Winform]安装在C盘,无操作权限的一个解决办法

标签:als   主程序   www.   安全   null   eof   source   void   上进   

原文地址:http://www.cnblogs.com/wolf-sun/p/7325205.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!