C#正确方式让程序以管理员权限启动

简介:     应用程序可能运行在各个windows版:windowsXp,win7-32bit,win7-64bit,win8-32bit,win8-64bit.由于windows各个版本的用户权限的限制不同,同一个开发环境编译出来的应用程序,拿到各个系统中运行的效果是用差别的。

    应用程序可能运行在各个windows版:windowsXp,win7-32bit,win7-64bit,win8-32bit,win8-64bit.由于windows各个版本的用户权限的限制不同,同一个开发环境编译出来的应用程序,拿到各个系统中运行的效果是用差别的。其主要原因还是win7、win8加强了对应用程序操作权限的限制。

一、一个明显的例子:

image

图1.1 Win8 普通用户下的cmd

image

图1.2  win8管理员下的cmd

pcmd

图1.3 win7运行CMD界面

    上面两个图中,win7 win8都是以Administrator登录的。但是,win7上直接在[运行]->CMD,直接是以管理员权限启动;而Win8直接在[运行]->CMD,进入的是普通权限的CMD界面,必须右键[以管理员身份运行]才能出现图1.2界面。

    网上的神人对于这个问题是这样回答的:

image

图1.4

 

二、权限限制在程序中使用命令行时中引发的问题

2.1、使用普通用户命令行去开启一些服务

image

图2.1

2.2、程序中以普通用户形式去开启一些服务:

image

图2.2

    2.1 和2.2的操作都失败了,原因就是应用程序的操作权限级数不够。

    这些问题该如何处理?

    有些解决方案是在我们调用到CMD的地方,直接使用下面的方式去调用管理员来启动CMD来执行相关命令行的命令:


  1. ProcessStartInfo startInfo = new ProcessStartInfo();
  2.                 startInfo.FileName = "cmd.exe";
  3.                 startInfo.Arguments = "/c C:\\Windows\\System32\\cmd.exe";
  4.                 startInfo.RedirectStandardInput = true;
  5.                 startInfo.RedirectStandardOutput = true;
  6.                 startInfo.RedirectStandardError = true;
  7.                 startInfo.UseShellExecute =false ;
  8.                 startInfo.Verb = "RunAs";
  9.                 Process process = new Process();
  10.                 process.StartInfo = startInfo;
  11.                 process.Start();
  12.                 process.StandardInput.WriteLine("bcdedit");
  13.                 process.StandardInput.WriteLine("exit");
  14.                 string strRst = process.StandardOutput.ReadToEnd();
  15.                 Bootinitext.AppendText("\n"+strRst );
  16.                 process.WaitForExit();

 

    实践证明,这种方法的在模块所在的应用程序不是以管理员权限启动时它是没什么作用的,它仍然是出现图2.2的结果。故解决方法应该是直接将应用程序的启动权限提升到管理员级别,主要参考下面代码:

在program.cs如下操作(案例)


  1. static void Main(string[] Args)
  2.         {
  3.             /**
  4.              * 当前用户是管理员的时候,直接启动应用程序
  5.              * 如果不是管理员,则使用启动对象启动程序,以确保使用管理员身份运行
  6.              */
  7.             //获得当前登录的Windows用户标示
  8.             System.Security.Principal.WindowsIdentity identity = System.Security.Principal.WindowsIdentity.GetCurrent();
  9.             //创建Windows用户主题
  10.             Application.EnableVisualStyles();

  11.             System.Security.Principal.WindowsPrincipal principal = new System.Security.Principal.WindowsPrincipal(identity);
  12.             //判断当前登录用户是否为管理员
  13.             if (principal.IsInRole(System.Security.Principal.WindowsBuiltInRole.Administrator))
  14.             {
  15.                 //如果是管理员,则直接运行

  16.                 Application.EnableVisualStyles();
  17.                 Application.Run(new Form1());
  18.             }
  19.             else
  20.             {
  21.                 //创建启动对象
  22.                 System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
  23.                 //设置运行文件
  24.                 startInfo.FileName = System.Windows.Forms.Application.ExecutablePath;
  25.                 //设置启动参数
  26.                 startInfo.Arguments = String.Join(" ", Args);
  27.                 //设置启动动作,确保以管理员身份运行
  28.                 startInfo.Verb = "runas";
  29.                 //如果不是管理员,则启动UAC
  30.                 System.Diagnostics.Process.Start(startInfo);
  31.                 //退出
  32.                 System.Windows.Forms.Application.Exit();
  33.             }
  34.         }

 

2.3、使程序以管理员权限启动的实际案例代码如下:


  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Windows.Forms;
  5. using System.Runtime.InteropServices;
  6. using System.IO;
  7. using System.Text;
  8. using System.Diagnostics;
  9. using System.Threading;

  10. namespace DatabaseCreate
  11. {
  12.     static class Program
  13.     {
  14.         #region Setting from ini document
  15.         [DllImport("kernel32")]
  16.         private static extern long WritePrivateProfileString(string Section, string key, string val, string filePath);
  17.         [DllImport("kernel32")]
  18.         private static extern int GetPrivateProfileString(string Section, string key, string def, /*StringBuilder reVal原来用StringBuilder*/byte[] buffer/*现在使用byte串*/, int Usize, string filePath);
  19.         [DllImport("kernel32")]
  20.         private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);
  21.         #endregion

  22.         ///
  23.         /// The main entry point for the application.
  24.         ///
  25.         [STAThread]
  26.         static void Main(string[] Args)
  27.         {
  28.             Application.EnableVisualStyles();
  29.             Application.SetCompatibleTextRenderingDefault(false);
  30.             //获取当前登录的Windows用户的标识
  31.             System.Security.Principal.WindowsIdentity wid = System.Security.Principal.WindowsIdentity.GetCurrent();
  32.             System.Security.Principal.WindowsPrincipal principal = new System.Security.Principal.WindowsPrincipal(wid);

  33.             // 判断当前用户是否是管理员
  34.             if (principal.IsInRole(System.Security.Principal.WindowsBuiltInRole.Administrator))
  35.             {
  36.                 byte[] bufferContent = new byte[255];
  37.                 string LanguageInfoPath = Application.StartupPath + "\\DayaSystemInfo.ini";

  38.                 FileInfo fileInfo = new FileInfo(LanguageInfoPath);
  39.                 string section = "Setting";
  40.                 string key = "Language";

  41.                 int returnNum = 0;
  42.                 /* 读取显示语言及处理 */
  43.                 if (fileInfo.Exists)
  44.                     returnNum = GetPrivateProfileString(section, key, "", bufferContent, (int)bufferContent.Length, fileInfo.ToString().Trim());

  45.                 string lanResult = "";
  46.                 int languageIndex = 0;
  47.                 if (returnNum != 0)
  48.                 {
  49.                     lanResult = Encoding.Default.GetString(bufferContent, 0, 1);
  50.                     if ((lanResult.Trim().Equals("1")) || (lanResult.Trim().Equals("0")))
  51.                     {
  52.                         languageIndex = Convert.ToInt32(lanResult);
  53.                     }
  54.                 }
  55.                 Application.Run(new Form1(languageIndex));
  56.             }
  57.             else // 用管理员用户运行
  58.             {
  59.                 System.Diagnostics.ProcessStartInfo startInfo = new ProcessStartInfo();
  60.                 startInfo.FileName = Application.ExecutablePath;
  61.                 startInfo.Arguments = string.Join(" ", Args);
  62.                 startInfo.Verb = "runas";
  63.                 System.Diagnostics.Process.Start(startInfo);
  64.                 System.Windows.Forms.Application.Exit();
  65.             }
  66.         }
  67.     }
  68. }

 

 

参考文档:

C#2010在Windows8—64系统,写的程序可以访问电脑(其他软件)的服务状态,但不能开启或关闭该服务

http://wenwen.soso.com/z/q419403029.htm

C#默认以管理员身份运行程序

http://blog.csdn.net/liushuijinger/article/details/8463574

相关文章
|
5月前
|
存储 SQL 数据库连接
C#程序调用Sql Server存储过程异常处理:调用存储过程后不返回、不抛异常的解决方案
本文分析了C#程序操作Sql Server数据库时偶发的不返回、不抛异常问题,并提出了解决思路。首先解析了一个执行存储过程的函数`ExecuteProcedure`,其功能是调用存储过程并返回影响行数。针对代码执行被阻塞但无异常的情况,文章总结了可能原因,如死锁、无限循环或网络问题等。随后提供了多种解决方案:1) 增加日志定位问题;2) 使用异步操作提升响应性;3) 设置超时机制避免阻塞;4) 利用线程池分离主线程;5) 通过信号量同步线程;6) 监控数据库连接状态确保可用性。这些方法可有效应对数据库操作中的潜在问题,保障程序稳定性。
393 11
|
12月前
|
缓存 C# Windows
C#程序如何编译成Native代码
【10月更文挑战第15天】在C#中,可以通过.NET Native和第三方工具(如Ngen.exe)将程序编译成Native代码,以提升性能和启动速度。.NET Native适用于UWP应用,而Ngen.exe则通过预编译托管程序集为本地机器代码来加速启动。不过,这些方法也可能增加编译时间和部署复杂度。
619 2
|
10月前
|
算法 Java 测试技术
Benchmark.NET:让 C# 测试程序性能变得既酷又简单
Benchmark.NET是一款专为 .NET 平台设计的性能基准测试框架,它可以帮助你测量代码的执行时间、内存使用情况等性能指标。它就像是你代码的 "健身教练",帮助你找到瓶颈,优化性能,让你的应用跑得更快、更稳!希望这个小教程能让你在追求高性能的路上越走越远,享受编程带来的无限乐趣!
428 13
|
12月前
|
API C#
C#实现Winform程序右下角弹窗消息提示
C#实现Winform程序右下角弹窗消息提示
593 1
|
C# 容器
C#中的命名空间与程序集管理
在C#编程中,`命名空间`和`程序集`是组织代码的关键概念,有助于提高代码的可维护性和复用性。本文从基础入手,详细解释了命名空间的逻辑组织方式及其基本语法,展示了如何使用`using`指令访问其他命名空间中的类型,并提供了常见问题的解决方案。接着介绍了程序集这一.NET框架的基本单位,包括其创建、引用及高级特性如强名称和延迟加载等。通过具体示例,展示了如何创建和使用自定义程序集,并提出了针对版本不匹配和性能问题的有效策略。理解并善用这些概念,能显著提升开发效率和代码质量。
434 4
|
12月前
|
设计模式 程序员 C#
C# 使用 WinForm MDI 模式管理多个子窗体程序的详细步骤
WinForm MDI 模式就像是有超能力一般,让多个子窗体井然有序地排列在一个主窗体之下,既美观又实用。不过,也要小心管理好子窗体们的生命周期哦,否则一不小心就会出现一些意想不到的小bug
923 0
|
Linux C# 开发者
Uno Platform 驱动的跨平台应用开发:从零开始的全方位资源指南与定制化学习路径规划,助您轻松上手并精通 C# 与 XAML 编程技巧,打造高效多端一致用户体验的移动与桌面应用程序
【9月更文挑战第8天】Uno Platform 的社区资源与学习路径推荐旨在为初学者和开发者提供全面指南,涵盖官方文档、GitHub 仓库及社区支持,助您掌握使用 C# 和 XAML 创建跨平台原生 UI 的技能。从官网入门教程到进阶技巧,再到活跃社区如 Discord,本指南带领您逐步深入了解 Uno Platform,并提供实用示例代码,帮助您在 Windows、iOS、Android、macOS、Linux 和 WebAssembly 等平台上高效开发。建议先熟悉 C# 和 XAML 基础,然后实践官方教程,研究 GitHub 示例项目,并积极参与社区讨论,不断提升技能。
379 2
|
12月前
|
XML 存储 安全
C#开发的程序如何良好的防止反编译被破解?ConfuserEx .NET混淆工具使用介绍
C#开发的程序如何良好的防止反编译被破解?ConfuserEx .NET混淆工具使用介绍
833 0
|
12月前
|
安全 API C#
C# 如何让程序后台进程不被Windows任务管理器强制结束
C# 如何让程序后台进程不被Windows任务管理器强制结束
398 0