我正在尝试编写一个需要管理员角色的 WinUI 3 桌面应用程序。它代表用户执行一些 msiexec 工作,据我所知,这几乎需要管理员。
应用程序本身将是未打包的 (
<WindowsPackageType>None</WindowsPackageType>
) 和独立的 (<WindowsAppSDKSelfContained>true</WindowsAppSDKSelfContained>
)。这两个设置都在 .csproj 文件中。
为了尝试获得管理员角色,我已将其添加到 app.manifest 文件中:
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
作为应用程序元素的一部分。我知道这应该足以确保应用程序以“管理员身份”运行,或者弹出 UAC 对话框来请求此类权限。
为了检查我们是否确实以管理员身份运行,我添加了这个函数,调用该函数来检查管理员状态:
public static bool IsAdmin()
{
var identity = WindowsIdentity.GetCurrent();
var principal = new WindowsPrincipal(identity);
return principal.IsInRole(WindowsBuiltInRole.Administrator);
}
如果我构建应用程序并在 Visual Studio 之外运行它,它会报告它不以管理员身份运行。没有 UAC,只需以标准用户身份运行应用程序(如果这是正确的术语)。
如果我右键单击并选择以管理员身份运行选项,则应用程序将运行并报告它正在以管理员身份运行。
如果我在 Visual Studio 调试器中运行它,它始终以管理员身份运行。但我确实以管理员身份运行 Visual Studio,所以也许它只是从父进程中获取它。不确定。
所以问题是为什么正常运行应用程序既不以管理员身份运行,也不弹出UAC对话框将其自身提升到该状态?我在app.manifest文件中做了一些根本错误的事情吗?应该有效吗?
对于清单、C#、WinUI 等来说,我是个新手,所以如果我做出无效的假设或者我不太理解你的答案,请耐心等待。很高兴填补我遗漏的任何空白。
我不确定最新的 WinAppSDK v1.2 是否支持提升的未打包应用程序。但放弃 WindowsApSDKSelfContained 似乎有效。
这是我尝试过的:
<WindowsPackagedType>None</WindowsPackagedType>
<!--<WindowsAppSDKSelfContained>true</WindowsAppSDKSelfContained>-->
<Capabilities>
<rescap:Capability Name="runFullTrust" />
<rescap:Capability Name="allowElevation" />
</Capabilities>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>
<Window
x:Class="ElevationTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid>
<TextBlock x:Name="AdministratorStatusTextBlock"/>
</Grid>
</Window>
MainWindow.xaml.cs
using Microsoft.UI.Xaml;
using System.Security.Principal;
namespace ElevationTest;
public sealed partial class MainWindow : Window
{
public MainWindow()
{
this.InitializeComponent();
AdministratorStatusTextBlock.Text = IsAdmin() is true
? "Running as admin."
: "NOT running as admin.";
}
public static bool IsAdmin()
{
var identity = WindowsIdentity.GetCurrent();
var principal = new WindowsPrincipal(identity);
return principal.IsInRole(WindowsBuiltInRole.Administrator);
}
}
应用程序应请求许可,并且文本应显示“以管理员身份运行。”。
我确信这只是我自己的无知,最初在 app.manifest 文件中放置代码时遇到了麻烦,但为了清楚起见,请确保代码位于根元素内
<assembly> </assembly>
。
对于新创建的 WinUI3 项目,以下是在 app.manifest 中输入代码的有效区域:
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<!-- Could place code here. -->
<assemblyIdentity version="1.0.0.0" name="NamespaceName.app"/>
<!-- Would work here too. -->
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
</application>
</compatibility>
<!-- Or here. -->
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
</windowsSettings>
</application>
<!-- I just so happened to have placed it here -->
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>
</assembly>