You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

使用UWP和C#调用关机功能时出现权限拒绝错误

解决UWP中调用ShutdownManager.BeginShutdown的权限被拒问题

别着急,这个E_ACCESSDENIED错误我帮不少开发者排查过,本质是UWP的沙箱安全模型限制——关机属于系统级敏感操作,默认普通UWP应用根本没有权限调用ShutdownManager.BeginShutdown,得满足几个前提条件才能正常执行:

首先,确认你的应用类型

纯UWP应用(完全沙箱化的那种)是不可能直接调用这个API的,必须是以下两种类型之一:

  • 桌面桥接(Desktop Bridge)应用:也就是打包成MSIX的Win32/WPF/WinForms应用
  • 带有桌面扩展的UWP应用

如果你的应用是纯UWP,直接跳过下面的步骤看「替代方案」。

步骤1:添加受限权限声明

打开你的Package.appxmanifest文件,切换到代码视图(可视化编辑器看不到这个权限):

  1. <Package>节点里添加命名空间:
    xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
    IgnorableNamespaces="uap mp rescap"
    
  2. <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,可以通过「桌面扩展+全信任进程」的方式间接执行关机:

  1. 创建一个简单的Win32控制台程序,里面写一行代码:
    System.Diagnostics.Process.Start("shutdown", "/s /t 1");
    
  2. 把这个控制台程序作为桌面扩展打包到你的UWP应用里。
  3. 在UWP应用里添加runFullTrust权限,然后用FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync()启动这个控制台程序,间接触发关机。

最后测试注意事项

测试的时候一定要侧载安装应用,并且确保运行时弹出管理员权限请求(如果没弹出,说明权限配置没到位),然后再触发label1.text == label2.text的逻辑,应该就能正常执行关机了。

内容的提问来源于stack exchange,提问作者Notwin

火山引擎 最新活动