简体   繁体   English

UAC实施最佳实践是什么? (。净)

[英]What are the UAC implementation best practices? (.NET)

I'm thinking about developing an application that should run as standard user most of the time, but for certain operations, elevated administrative access will be required. 我正在考虑开发一个应该在大多数时间以标准用户身份运行的应用程序,但对于某些操作,将需要提升管理访问权限。 The user expecience should be like in Windows Explorer when copying something into a protected folder. 在将某些内容复制到受保护的文件夹时,用户的特性应该与Windows资源管理器中的一样。

Now the question is, how should this be implemented in .NET? 现在问题是,如何在.NET中实现它? I know that only entire processes or maybe some COM instances can be elevated, not single functions. 我知道只有整个进程或某些COM实例可以升级,而不是单个函数。 But that would be exactly what I need. 但这正是我所需要的。 What path should I go? 我应该走哪条路? Write two executables, one with a manifest and the other without; 写两个可执行文件,一个带清单,另一个没有; programmatically run the same process elevated a second time; 以编程方式运行第二次提升的相同进程; use some COM thing? 使用一些COM的东西? Then I have the added privileges, but how to tell the other process what to do? 然后我有添加的权限,但如何告诉其他进程该怎么办? Use .NET remoting (which is deprecated/complicated?); 使用.NET远程处理(已弃用/复杂?); implement my own IPC thing using sockets/pipes/whatever? 使用套接字/管道/什么来实现我自己的IPC事物? That elevated task may need to ask the user something in the middle of the process. 升级的任务可能需要在过程中间询问用户某些事情。 And it must be cancellable. 它必须是可以取消的。

There's a lot that tells me how UAC is working in the inside or how system administrators can configure it, but I haven't found anything that answers these basic questions. 有很多东西告诉我UAC如何在内部工作或系统管理员如何配置它,但我没有找到任何可以解答这些基本问题的东西。

We appear to have 2 distinct questions here: 我们这里似乎有2个不同的问题:

  1. How should I handle operations that require elevated privileges? 我该如何处理需要提升权限的操作?
  2. If I use a separate process how should I tell the other process what to do? 如果我使用单独的流程,我该如何告诉其他流程该怎么做?

Here's my attempt to answer them: 这是我试图回答它们:

  1. It appears that from this SO Question: Windows 7 and Vista UAC - Programmatically requesting elevation in C# that the solution is as you suggested in your question (to run another process and have it request elevation on launch) is the 'right answer' 似乎从这个SO问题: Windows 7和Vista UAC - 以编程方式请求提升C#解决方案正如您在问题中建议的那样(运行另一个进程并在启动时请求提升)是'正确答案'
  2. As far as telling the other process what to do, here is how I would take a stab at it: 至于告诉其他过程该做什么,这里是我如何采取它:

I would start by splitting out each of the actions that required elevated privileges to their own 'helper' programs. 我首先将每个需要提升权限的操作拆分为他们自己的“帮助程序”。 These helper programs would perform only a single action, taking arguments via the command line. 这些帮助程序只执行一个操作,通过命令行获取参数。

For example say your program needs to stop/start a service, I'd write a small helper program called servicecontroller (well in reality you'd probably want to use the net command) that took command line arguments similar to this: 例如,假设您的程序需要停止/启动服务,我会编写一个名为servicecontroller的小帮助程序(实际上您可能想要使用net命令),它接受类似于此的命令行参数:

servicecontroller stop MyCoolService
servicecontroller start MyCoolService

These arguments would be built up by the 'Main' program and passed along after hitting 'OK'. 这些参数将由'Main'程序构建,并在点击'OK'后传递。

There are several issues with the solution above though, that you may or may not care about: 上面的解决方案有几个问题,您可能会或可能不会关心:

  1. You are passing arguments on the command line, which can be easily sniffed 您正在命令行上传递参数,这些参数很容易被嗅探
  2. You are limited by the length of the ProcessStartInfo.Argument + Program Path (from MSDN: The length of the arguments added to the length of the full path to the process must be less than 2080. ) 您受ProcessStartInfo.Argument + Program Path 的长度限制 (来自MSDN: 添加到进程的完整路径长度的参数长度必须小于2080.
  3. Getting information passed back to you might be a little tricky (should you need this) 获取传递给您的信息可能有点棘手(如果您需要)

A bit more googling revealed this blog post by 'DevZest' which basically recommends what I've described above. 更多的谷歌搜索透露了这个博客文章'DevZest' ,基本上推荐了我上面所描述的。 Good luck! 祝好运!


EDIT Based on the additional questions asked in the comments: 编辑根据评论中提出的其他问题:

  1. Would you recommend starting a separate executable or the same executable when needing to perform elevated actions? 您是否建议在需要执行提升操作时启动单独的可执行文件或相同的可执行文件?
  2. (I'm reading between the lines on this one) How often should I prompt the user for these actions? (我正在阅读这一行之间的界限)我应该多久提示用户进行这些操作?

Without knowing exactly what you're doing here is my take on it: 我不知道你在这里做了什么,我的看法是:

  1. I would personally have separate executables for each of those actions, but not knowing exactly what you're trying to do its hard to make this call. 我个人会为每个操作分别设置可执行文件,但不知道你正在努力做什么,这很难做出这个调用。 In general though it seems like you'd want a separate process for each elevated action. 总的来说,虽然看起来你想要为每个提升动作单独一个进程。
  2. I am a bit confused by your second example, once again without knowing exactly what you're attempting to do I'll just go based off the examples you gave in your comment. 我对你的第二个例子感到有点困惑,再一次不知道你究竟想要做什么我将根据你在评论中给出的例子。

In the file manager example I would do what explorer does and first spin though each of the destination directory to determine if any of the destination locations require elevated privileges to copy to. 在文件管理器示例中,我将执行资源管理器的操作,并首先在每个目标目录中进行旋转,以确定是否有任何目标位置需要提升权限才能复制到。 If they do I would mark a flag indicating that the action needs to be performed as an administrator, prompt the user and then perform the entire action as an administrator. 如果他们这样做,我会标记一个标志,表明该操作需要以管理员身份执行,提示用户,然后以管理员身份执行整个操作。

As to the text editor example, I would do something similar as above, when the user gives you a destination directory check to see that you have write access to that location, if not inform the user that they are saving to a location that requires elevation, save their work to a writable location (your program's APPDATA is probably a good place or even TEMP ), then fire off the copy procedure which requests elevation, if the user cancels the UAC dialog make sure that you capture this cancel and delete the temporary file. 至于文本编辑器示例,我会做类似上面的事情,当用户给你一个目的地目录检查,看看你有对该位置的写入权限,如果没有通知用户他们正在保存到需要提升的位置,将他们的工作保存到可写位置(您的程序的APPDATA可能是一个好地方甚至是TEMP ),然后触发请求提升的复制过程,如果用户取消UAC对话框,请确保捕获此取消并删除临时文件。

I would discourage you from keeping an elevated worker process around, if you find that your program needs to request elevation more than a few times (Readas: 1 or 2 corner cases) during the programs lifespan, then I would question why it wasn't marked as always elevated. 如果你发现你的程序需要在程序生命周期内请求提升超过几次(Readas:1或2个极端情况),我会阻止你保持高级工作程序,那么我会质疑为什么它不是标记为始终提升。 I like to follow the rule of 'least surprise', when I gave you elevated rights I expect you to only perform the action that requested it, not to continue to pump actions that require elevation through the first request. 我喜欢遵循“最少惊喜”的规则,当我给你提升权利时,我希望你只执行请求它的动作,而不是继续在第一个请求中抽取需要提升的动作。

All of that being said there is nothing to prevent you from doing the above, once you let some process get elevated rights he can invite in all of his buddies. 所有这一切都说没有什么可以阻止你做上述事情,一旦你让一些过程得到提升的权利,他可以邀请他所有的朋友。 Based on your desire to keep an elevated process around why not just save the current state of the program, and relaunch the program with elevated privileges and restore the state? 基于您希望保持升级过程的原因,为什么不仅仅保存程序的当前状态,并使用提升的权限重新启动程序并恢复状态? This, in my opinion, is the same as having the worker process exist in an always elevated state. 在我看来,这与将工作流程存在于始终处于高位状态的情况相同。

If you could tell us more about exactly what you're trying to do we might be able to find better ways to accomplish that, without having to run into UAC issues. 如果您可以告诉我们更多关于您正在尝试做什么的信息,我们可以找到更好的方法来实现这一目标,而不必遇到UAC问题。 While there are some very good reasons to write to areas protected by UAC, in most cases programs do not need to write/access to those locations. 虽然写入受UAC保护的区域有一些很好的理由,但在大多数情况下,程序不需要写入/访问这些位置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM