使用UWP和C#调用关机功能时出现权限拒绝错误
解决UWP中调用ShutdownManager.BeginShutdown的权限被拒问题
别着急,这个E_ACCESSDENIED错误我帮不少开发者排查过,本质是UWP的沙箱安全模型限制——关机属于系统级敏感操作,默认普通UWP应用根本没有权限调用ShutdownManager.BeginShutdown,得满足几个前提条件才能正常执行:
首先,确认你的应用类型
纯UWP应用(完全沙箱化的那种)是不可能直接调用这个API的,必须是以下两种类型之一:
- 桌面桥接(Desktop Bridge)应用:也就是打包成MSIX的Win32/WPF/WinForms应用
- 带有桌面扩展的UWP应用
如果你的应用是纯UWP,直接跳过下面的步骤看「替代方案」。
步骤1:添加受限权限声明
打开你的Package.appxmanifest文件,切换到代码视图(可视化编辑器看不到这个权限):
- 在
<Package>节点里添加命名空间:xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities" IgnorableNamespaces="uap mp rescap" - 在
<Capabilities>节点下添加关机权限:<rescap:Capability Name="shutdown" />
注意:这个是微软的受限权限,如果你要把应用提交到微软商店,需要额外提交权限申请并说明用途;如果是企业内部侧载应用,直接用就行。
步骤2:确保应用以管理员身份运行
光加权限还不够,桌面桥接应用默认是普通权限,必须提升到管理员才能执行关机操作:
- 如果你是桌面桥接的Win32应用:可以在主程序的项目属性里,找到「安全性」选项,勾选「启用ClickOnce安全设置」,然后把权限级别改成「完全信任(管理员)」。
- 如果你是带桌面扩展的UWP应用:在
Package.appxmanifest的<Application>节点下添加:
同时在<rescap:Capability Name="runFullTrust" /><Properties>节点里添加:<rescap:RunWithHostProcess>true</rescap:RunWithHostProcess>
替代方案(纯UWP应用适用)
如果你的应用是纯UWP,没法用ShutdownManager,可以通过「桌面扩展+全信任进程」的方式间接执行关机:
- 创建一个简单的Win32控制台程序,里面写一行代码:
System.Diagnostics.Process.Start("shutdown", "/s /t 1"); - 把这个控制台程序作为桌面扩展打包到你的UWP应用里。
- 在UWP应用里添加
runFullTrust权限,然后用FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync()启动这个控制台程序,间接触发关机。
最后测试注意事项
测试的时候一定要侧载安装应用,并且确保运行时弹出管理员权限请求(如果没弹出,说明权限配置没到位),然后再触发label1.text == label2.text的逻辑,应该就能正常执行关机了。
内容的提问来源于stack exchange,提问作者Notwin




