[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/wolf-sun/
博客版权:如果文中有不妥或者错误的地方还望高手的你指出,以免误人子弟。如果觉得本文对你有所帮助不如【推荐】一下!如果你有更好的建议,不如留言一起讨论,共同进步! 再次感谢您耐心的读完本篇文章。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
2015-08-09 [Asp.net]缓存简介
2014-08-09 [Asp.net MVC]Asp.net MVC5系列——实现编辑、删除与明细信息视图