前几天,我遇到了一个应用程序,当你运行它时,它会出现 UAC 屏幕并请求以管理员权限运行。在 UAC 屏幕上单击“是”可以正常运行应用程序。有趣的是,如果您单击“否”,应用程序仍会运行,而不是退出,而是在有限的用户帐户中运行(当然,功能较少)。
我的问题是,如何配置我的 C# 应用程序来执行此操作?我知道我的应用程序可以有一个应用程序清单以提升的权限运行,但是我如何复制我刚才解释的那种行为呢?
要使用不同的提升应用程序执行此操作,您可以使用“启动器”(或启动器是“普通”应用程序)。
如果您想要三个应用程序,您可能有一个 WinForms 启动器,例如:
[STAThread]
static void Main()
{
const int ERROR_CANCELLED = 1223;
try
{
Process.Start("el.exe");
// ran el in elevated node...
}
catch (Win32Exception ex)
{
if (ex.NativeErrorCode == ERROR_CANCELLED)
{
Process.Start("normal.exe");
}
}
}
如果您正在执行两个应用程序,则可以执行以下操作:
[STAThread]
static void Main()
{
const int ERROR_CANCELLED = 1223;
try
{
Process.Start("el.exe");
// ran el in elevated node...
}
catch (Win32Exception ex)
{
if (ex.NativeErrorCode == ERROR_CANCELLED)
{
// "continue" as un-elevated app.
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
您可以将所有代码保存在一个应用程序中。应用程序清单不要求应用程序运行提升,它使用asInvoker
级别。
当应用程序启动时,它会尝试重新启动提升自身。我的意思是它用runas
动词开始了另一个过程。如果成功,那么第一个实例就存在了。
如果提升不成功,那么它会继续以有限的功能运行。
但是考虑一下用户体验:
并非世界上的每个人都以管理员身份工作。对于他们来说,提升看起来不像是点击Continue
按钮,UAC 会要求他们提供管理员的用户名和密码。
从这个角度来看,微软推荐的方法效果很好:作为普通用户运行,直到你真的需要提升。所有高程点都应在 UI 中清楚地标记。您仍然可以使用同一个 exe 文件来运行非提升和提升的实例,但您必须实现一种通信机制,以便非提升的实例可以提供所有数据来执行用户请求的操作。一旦你启动了提升的实例,你可以保持它运行并退出非提升的实例,这样就可以在没有提升的情况下执行其他操作。
因此这意味着更多的努力,但更好的用户体验。