在Winform程序中设置管理员权限及为用户组添加写入权限

原文:在Winform程序中设置管理员权限及为用户组添加写入权限

在我们一些Winform程序中,往往需要具有一些特殊的权限才能操作系统文件,我们可以设置运行程序具有管理员权限或者设置运行程序的目录具有写入的权限,如果是在操作系统里面,我们可以设置运行程序以管理员身份运行,或者设置Users用户组在运行目录中具有写入权限都可以解决问题,不过如果我们想通过C#代码进行自动的处理,那么应该如何实现呢?

1、系统设置管理员权限或者目录写入权限

如果我们需要让程序以管理员身份运行,那么可以通过设置快捷方式的属性或者应用程序的属性为【以管理员身份运行此程序】即可实现,如下所示。

如果我们需要一些写入文件的权限,如我们程序可能需要操作SQLite文件数据库,那么也可以通过设置Users用户组在运行目录中具有写入权限都可以解决问题,否则可能会出现【 attempt to write a readonly database】的错误。

我们设置步骤如下所示:找到SQLite数据库所在的文件夹,单击右键,属性->安全,为Users用户组添加写入权限。

 

2、使用C#代码实现

上面的步骤可以解决我们实际碰到的权限访问问题,那么我们如果使用C#代码,应该如何实现这些操作呢?

对于第一个以管理员身份运行程序的处理操作,我们是可以通过程序修改配置的方式实现,这样可以避免一些Winform程序运行时刻的权限问题:

1)在通过winform程序执行cmd命令时,某些情况下如果不是以管理员身份运行,则会提示命令无效。

2)或者通过winform程序执行Windows Service 服务时,也需要以管理员身份才能调用Service服务。

3)处理其他需要管理员身份的相关操作。

我们如果是编译Winform程序,只需要几步就可以在让程序在运行的时候获得管理员身份,如下所示在我们Winform的UI项目【属性】【安全性】里面,勾选ClickOne的设置。

然后我们就可以看到在UI项目【Properties】目录里面,生成了一个app.manifest文件。

这个app.manifest文件是自动生成的,我们修改其中的一项设置,然后取消上面勾选ClickOne的设置就可以了。

把其中app.manifest文件的内容:

<requestedExecutionLevel level="asInvoker" uiAccess="false" />

改为:

<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />

即可,这样取消上面勾选ClickOne的设置,然后重新编译整个程序即可。

在程序运行的时候,会提示“用户账户控制”来获取管理员权限运行,点击“是”则获取了管理员权限。

 

对于需要为指定目录设置用户组权限,那么也是可以通过C#代码进行处理的。

一般情况下,我们可以在程序安装或者启动的时候,对目录进行用户组权限的处理,这样程序运行起来就自然具有对应目录的读写权限了。

如我们在程序启动的时候处理,那么我们可以在Main函数的里面进行设置。

        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        private static void Main()
        {

        }

为了方便处理,我们添加一个公共的函数,用来处理用户组的目录权限访问操作,C#代码如下所示。

        /// <summary>
        /// 为指定用户组,授权目录指定完全访问权限
        /// </summary>
        /// <param name="user">用户组,如Users</param>
        /// <param name="folder">实际的目录</param>
        /// <returns></returns>
        private 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;
        }

然后我们在Main函数里面进行调用就可以了。

        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        private static void Main()
        {
            //为用户组指定对应目录的完全访问权限
           SetAccess("Users", Application.StartupPath);

            //界面汉化
            System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("zh-Hans");
            DevExpress.UserSkins.BonusSkins.Register();
            DevExpress.Skins.SkinManager.EnableFormSkins();

            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);

            //登录界面
            Login dlg = new Login();
            dlg.StartPosition = FormStartPosition.CenterScreen;
            if (DialogResult.OK == dlg.ShowDialog())
            {
                if (dlg.bLogin)
                {
                    SplashScreen.Splasher.Show(typeof(SplashScreen.frmSplash));

                    gc.MainDialog = new MainForm();
                    gc.MainDialog.StartPosition = FormStartPosition.CenterScreen;

                    Application.Run(gc.MainDialog);
                }

            }
            dlg.Dispose();
        }

这样在程序运行后,我们就可以看到对应目录具有完全的读写操作权限了,这样对于一些如读写SQLite出错的问题,也就迎刃而解了。

以上就是我对于两种不同权限访问的处理经验总结,希望给在Winform开发中的同行参考,感谢耐心的阅读和支持。

 

时间: 2024-11-03 12:59:33

在Winform程序中设置管理员权限及为用户组添加写入权限的相关文章

注册表-64位操作系统下,如何用程序实现设置管理员权限和兼容性

问题描述 64位操作系统下,如何用程序实现设置管理员权限和兼容性 在线急用.目前有一个需要在U盘上运行的程序,通过注册表来实现管理员权限和兼容性设置,(注册表位置:HKEY_CURRENT_USERSoftwareMicrosoftWindows NTCurrentVersionAppCompatFlagsLayers,需要设置键名称为可执行文件的全路径,键值为WINXPSP3 RUNASADMIN),在win7 32位系统上正常,可执行文件的全路径就是盘符+目录名+文件名,但是在win7 64

C# winform 程序中触摸屏开发问题

问题描述 C# winform 程序中触摸屏开发问题 用C#写的winform程序,应用到触摸屏上,所有操作监控鼠标事件,但是在触摸屏上出现当手指按下时没有响应鼠标事件(mousedown),在手指抬起后触发了mousedown和mouseup事件.我记得有个Api可以设置触摸屏防止无意触碰触发事件的.但是忘记是哪个函数了(win32 Api).请问谁知道!麻烦告诉我一下. QQ 908567476 谢谢! 解决方案 关于C#的WinForm程序打包的问题 解决方案二: 关于C#的WinForm

从WinForm程序中显示WPF Window出现“The URI prefix is not recognized”异

从WinForm程序中显示WPF Window出现"The URI prefix is not recognized"异常的解决方法 从WinForm App中显示WPF窗口的代码: MyWindow wpfWindow = new MyWindow(); WindowInteropHelper wih = new WindowInteropHelper(wpfWindow); wih.Owner = ownerHwnd; wpfWindow.ShowDialog(); 一般情况下,这

android开发如何在程序中设置双卡手机来电铃声

问题描述 android开发如何在程序中设置双卡手机来电铃声 如题,对单卡手机的我知道. 就是不知道双卡手机有没有什么不一样的地方. 解决方案 http://www.android-study.net/listxx.aspx?id=658 这个博客 写的还不错

两个独立的winform程序中,如何传递form窗体界面?

问题描述 就是在客户端Winform程序中的一个form窗体,需要在Server端Winform程序中完整的展现出来,目前想到了两种方式:第一种方式:将客户端程序中的form窗体做截图,直接传递到B程序.这样做传输量太大,再者有滚动条的界面展示不出来,不好用:第二种方式:将客户端程序Form窗体中的所有控件属性(大小,位置,值等等)当作参数,传递到Server端程序,在Server端程序中重新构建界面:这样需要传递的各种元素太多,比较麻烦.请教各位高手,还有没有其他比较好的方法么? 解决方案 解

Python程序中设置HTTP代理_python

0x00 前言 大家对HTTP代理应该都非常熟悉,它在很多方面都有着极为广泛的应用.HTTP代理分为正向代理和反向代理两种,后者一般用于将防火墙后面的服务提供给用户访问或者进行负载均衡,典型的有Nginx.HAProxy等.本文所讨论的是正向代理. HTTP代理最常见的用途是用于网络共享.网络加速和网络限制突破等.此外,HTTP代理也常用于Web应用调试.Android/IOS APP 中所调用的Web API监控和分析,目前的知名软件有Fiddler.Charles.Burp Suite和mi

.Net中导出数据到Excel(asp.net和winform程序中)_实用技巧

一.asp.net中导出Excel的方法: 在asp.net中导出Excel有两种方法,一种是将导出的文件存放在服务器某个文件夹下面,然后将文件地址输出在浏览器上:一种是将文件直接将文件输出流写给浏览器.在Response输出时,t分隔的数据,导出Excel时,等价于分列,n等价于换行. 1.将整个html全部输出Excel 此法将html中所有的内容,如按钮,表格,图片等全部输出到Excel中. 复制代码 代码如下: Response.Clear(); Response.Buffer= tru

WinForm程序中使用控制台作为输出窗口

Lambda表达比代表定义和带外方法定义的结合更清楚,且相关的额外工作只需要满足语言定义即可.不过,它也有一些不足之处.如果某个方法的参数包含System.Delegate 这样的抽象类型,用lambda表达式介绍特殊的问题:C#编译器不能将lambda表达式转换成还未明确定义的衍生代表类型. 如果不仔细思考一下,你的代码看上去就会像是来自.NET1.0的东西.在本文中,我将告诉告诉你为什么lambda表达式不足以被直接转换成抽象代表类型,并且教你怎样使得编译器转换你所定义的指定代表.解决方案依

在WEB程序中设置个性化,容错提示窗口

web|程序|容错 首先设计一个容错提示的窗口图像为如下: 关键HTML文本如下: "原因:<%=content[Int32.Parse(Request.QueryString["ms"])]%>" 然后在代码编辑窗口中添加如下不分: public class WebForm1 : System.Web.UI.Page { public string[] content; private void Page_Load(object sender, Sys