海拔要求不适用于 winforms 应用程序中的方法
我有一个 winforms 应用程序,可以循环安装其他应用程序。这在 Windows 7 中的管理员帐户上可以正常工作,但我在标准帐户中遇到严重问题 - 该应用程序需要提升才能写入“Program Files(x86)”文件夹。
因此,我尝试使用以下代码在 winforms c# 应用程序中请求特定方法(运行安装程序的方法)的提升:
[System.Security.Permissions.PrincipalPermission(System.Security.Permissions.SecurityAction.Demand, Role = @"BUILTIN\Administrators")]
收到错误后,我从网上了解到,在调用带有上述属性的方法之前,我需要这样写:
AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
我这样做了,该方法仍然抛出以下错误:
请求主体权限失败。
逐步调试通过 SetPrincipalPolicy 行,但是当它到达具有 Demand 属性的方法时,它只是抛出相同的错误,就好像 SetPrincipalPolicy 从未存在过一样。
我在正确设置需求属性时做错了什么吗?
先感谢您。
稍后编辑:按照此处的要求,应该在静默安装应用程序时触发提升请求的代码(但不起作用):
WindowsPrincipal principal = new WindowsPrincipal(WindowsIdentity.GetCurrent());
bool hasAdministrativeRight = principal.IsInRole(WindowsBuiltInRole.Administrator);
if (!hasAdministrativeRight)
{
ProcessStartInfo psi = new ProcessStartInfo(file);
psi.WindowStyle = ProcessWindowStyle.Hidden;
psi.UseShellExecute = true;
psi.Verb = "runas";
//psi.CreateNoWindow = true;
psi.Arguments = modifiers;
try
{
using (Process process = Process.Start(psi))
{
process.WaitForExit();
if (process.HasExited)
return process.ExitCode;
}
}
catch (Win32Exception wex)
{
}
}
我需要的是,该过程会弹出一个对话框,询问管理员的用户名和密码,如果该应用程序在 Windows 标准用户下运行。只有上面以编程方式启动的进程才应该以管理员身份运行,主应用程序本身可以保留为标准用户。
I have a winforms app that installs other apps in a loop. This works properly on an administrator account in Windows 7, but I have serious issues in a standard account - the app requires elevation in order to write to "Program Files(x86)" folder.
Therefore I am trying to ask for elevation for a specific method (the one that runs the installers) in a winforms c# app, using this code:
[System.Security.Permissions.PrincipalPermission(System.Security.Permissions.SecurityAction.Demand, Role = @"BUILTIN\Administrators")]
After receiving an error, I learned from the web that before calling the method which carries the above attribute, I need to write this:
AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
I did this, and the method still throws the following error:
Request for principal permission failed.
Step by step debugging passes the SetPrincipalPolicy line but, when it reaches the method with the Demand atribute, it just throws the same error, as if the SetPrincipalPolicy never existed.
Am I doing something wrong in setting the Demand attribute properly?
Thank you in advance.
LATER EDIT: as requested here is the code that is supposed to trigger the elevation request when installing the app silently (but does not work):
WindowsPrincipal principal = new WindowsPrincipal(WindowsIdentity.GetCurrent());
bool hasAdministrativeRight = principal.IsInRole(WindowsBuiltInRole.Administrator);
if (!hasAdministrativeRight)
{
ProcessStartInfo psi = new ProcessStartInfo(file);
psi.WindowStyle = ProcessWindowStyle.Hidden;
psi.UseShellExecute = true;
psi.Verb = "runas";
//psi.CreateNoWindow = true;
psi.Arguments = modifiers;
try
{
using (Process process = Process.Start(psi))
{
process.WaitForExit();
if (process.HasExited)
return process.ExitCode;
}
}
catch (Win32Exception wex)
{
}
}
What I need, is for that process to pop a dialog asking for username and password for admin, if the app was ran under a Windows Standard User. Only the process started programmatically above should run as admin, the main app itself can remain as a standard user.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这不是 UAC 的工作方式。它是基于流程的,当您启动新流程时,用户只会收到“请让我弄乱您的机器”提示。程序中嵌入了“我需要用户同意才能扰乱机器,请说是”的正确咒语。您可以通过 执行此操作这个答案。
使其基于方法的想法已死。对程序员来说不合理,对用户来说有意义。用户获胜。
This is just not the way UAC works. It is process based, the user only ever gets the "please let me mess with your machine" prompt when you start a new process. With the proper incantation of "I need the user's consent to mess with the machine, please say Yes" signal embedded in the program. Which you do by this answer.
Death to the idea of making it method based. Unreasonable to a programmer, makes sense to a user. User wins.
您可以强制您的应用程序始终以管理员身份运行。 这就是这样你就这么做。但不建议您的应用程序需要管理员权限才能运行。
如果您启动
进程
来运行安装程序,您可以检查这里如何以管理员身份运行该进程。Visual Studio 使用的第三个选项是,当您执行需要管理员权限的操作时,系统会提示您重新启动应用程序,然后它会以管理员身份重新启动应用程序,您就可以执行任务。只需使用第二种方式中的代码即可启动您的应用程序。
您发布的以管理员身份运行的方法将检查用户是否是管理员,然后以管理员身份启动该过程。如果用户没有管理员权限,应用程序甚至不会启动。更好的解决方案是始终尝试以管理员身份运行该流程。然后用户将收到包含密码和用户名的 UAC 提示,管理员可以填写这些内容。
You can either force your app to always run as an admin. This is how you do that. It is not recommended however for your app to need admin privileges to run.
If you start a
Process
to run the installer, you can check here how to run the process as an admin.A third option which Visual Studio uses is that when you do something where you need admin privileges you are prompted to restart the app and it then restarts the app as an admin and you can perform the tasks. Just use the code from the second way to start your app.
The method you've posted to run as admin will check if the user is admin and then start the process as an admin. If the user doesn't have admin rights the app won't even start. A better solution is to always try to run the process as an admin. Then the user will get an UAC prompt with password and username, which an admin can fill in.