题
我有一个控制台应用程序,需要使用一些需要管理员级别的代码。我读到我需要添加一个清单文件 myprogram.exe.manifest ,如下所示:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="requireAdministrator">
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
但它仍然不会引发 UAC(在控制台中或在 VS 中调试)。我该如何解决这个问题?
更新
如果我在管理员中运行解决方案或在管理员中运行 /bin/*.exe ,我就可以使其工作。我仍然想知道是否有可能在应用程序启动时弹出一些内容,而不是明确右键单击>以管理员身份运行?
解决方案
您需要将UAC清单嵌入为嵌入式Win32资源。请参阅将UAC清单添加到托管代码。
简而言之,您使用Windows SDK命令行工具将其嵌入到可执行文件中。
通过将以下行作为后期构建任务放在VS项目的属性中,您可以将其作为构建后步骤自动执行:
mt.exe -manifest "$(ProjectDir)$(TargetName).exe.manifest" -updateresource:"$(TargetDir)$(TargetName).exe;#1"
其他提示
对于任何使用 Visual Studio 的人来说,这都非常简单。我正要设置 Windows SDK 并执行 mt.exe 构建后步骤以及所有这些,然后才意识到它已内置到 VS 中。我想我应该把它记录下来供后代使用。
- 项目|添加新项目 - > Visual C#项目 - >应用程序清单文件
- 打开app.manifest,将requestedExecutionLevel.@level更改为“requireAdministrator”
- 建造
田田
Scott的回答将按照您的要求进行,但Microsoft建议控制台应用程序显示“拒绝访问”。消息而非提示提升。
来自 http://msdn.microsoft.com/en-us/library /bb756922.aspx :
控制台应用程序在控制台窗口上显示其输出而不是 具有单独的用户界面。如果应用程序需要完整的管理员 访问令牌运行,然后该应用程序需要从中启动 一个高架的控制台窗口。
您必须对控制台应用程序执行以下操作:
标记您的应用程序&#8220; asInvoker&#8221;:您可以通过创建应用程序的清单来执行此操作,您可以在其中设置RequestedExecutionLevel == asInvoker。此设置允许来自非提升上下文的呼叫者创建您的流程,从而允许他们继续执行步骤2.
- 醇>
如果在没有完全管理员访问令牌的情况下运行应用程序,则提供错误消息:如果应用程序是在非提升的控制台中启动的,则应用程序应提供简短消息并退出。建议的消息是:“拒绝访问”。使用所选选项需要管理员权限。使用管理员命令提示符完成这些任务。“
应用程序还应在启动失败时返回错误代码ERROR_ELEVATION_REQUIRED以便于编写脚本。
我的C#代码如下。它在Windows XP(管理员 - > ok,标准用户 - &gt;拒绝)和Windows Server 2008(提升管理员 - >确定,非提升管理员 - &gt;拒绝,标准用户 - &gt;拒绝)上进行测试。
static int Main(string[] args)
{
if (!HasAdministratorPrivileges())
{
Console.Error.WriteLine("Access Denied. Administrator permissions are " +
"needed to use the selected options. Use an administrator command " +
"prompt to complete these tasks.");
return 740; // ERROR_ELEVATION_REQUIRED
}
...
return 0;
}
private static bool HasAdministratorPrivileges()
{
WindowsIdentity id = WindowsIdentity.GetCurrent();
WindowsPrincipal principal = new WindowsPrincipal(id);
return principal.IsInRole(WindowsBuiltInRole.Administrator);
}