问题描述
- C#管理员权限以及多进程的问题
-
正在用C#写一个能通过窗口来进行链接(mklink)的小程序。
一、由于mklink需要管理员权限运行,所以程序与必须使用高 权限。于是很快的写出了代码,感觉不错。但是依靠复制来获取链接路径还是 很不方便,于是尝试加入拖拽文件(夹)获取路径的功能。
二、通过网上的资料,很快写好了该功能。但是问题出现了。因为win7的权限问题,导致在高权限下拖拽无法获得路径。普通权限是可以的。
三、于是又开始百度,找到了一种消息过滤的方法,大喜,写好了代码,问题依在,于是又上网查,发现winform程序的拖拽并没有用消息机制,而是用的API回掉
四、无语中,于是想到了一下办法,先启动一个高权限进程作为后台,再由该高权限进程创建一个用户权限窗体进程。获取拖拽路径后窗体进程像后台进程发送数据以启动后台进程实现mklink命令。
问题是如何实现上诉的思想呢?
解决方案
di典型的服务,普通应用架构
服务进程处理去高权限的工作,普通应用处理winform。
进程间通信来交换数据
解决方案二:
程序提高权限有两种做法,一个是整体提高权限,也就是通过manifest实现。一个是给某个方法提高权限,用PrincipalPermission实现。
解决方案三:
比如说你调用mklink的方法
[PrincipalPermission(SecurityAction.Demand, Role = @"BUILTINAdministrators")]
void method(...)
{
...
}
这样你的主程序本身是没有提权的,只是调用这个方法才提权。
解决方案四:
倒过来就容易多了:让普通权限进程去启动一个高权限进程(当然是通过UAC授权)。
这个可以通过Process.StartInfo.Verb = "runas";来实现。它相当于你右击一个程序,并选择'Run as administrator'。
static void StartCmdServer(int listenningPort)
{
Process p = new Process();
p.StartInfo.Verb = "runas"; // 相当于你右击一个程序,并选择'Run as administrator'
p.StartInfo.FileName = System.Reflection.Assembly.GetEntryAssembly().Location;
p.StartInfo.Arguments = " /server /port:" + listenningPort;
p.Start();
}
你的程序app.manifest中要去掉requireAdministrator,并用命令行参数来决定是运行普通进程,还是高权限进程:
[STAThread]
static void Main(string[] args) // 加上string[] args
{
Program.IsCmdServer = args.Any(arg => arg.ToLower() == "/server");
if (Program.IsCmdServer)
{
RunAsServer(args);
}
else
{
Program.CmdSender = CmdSender.Start();
StartCmdServer(Program.CmdSender.BoundPort);
}
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
时间: 2024-09-12 12:55:24