分享

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

 地质博士 2018-08-05

    应用程序可能运行在各个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

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多