UWP通常是没有让设备关机和重启的权限的。但是在Windows 10 IoT Core中是有办法实现的。安装Windows 10 Iot Core之后默认启动的那个欢迎页面右上角是有关机和重启按钮的。其实就是个UWP,它的源代码在:https://github.com/ms-iot/samples/tree/develop/IoTCoreDefaultApp
分析源代码可以发现,关机和重启是通过ShutDownManager这个class实现的。
#region Assembly Windows.System.SystemManagementContract, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null, ContentType=WindowsRuntime
// C:\Program Files (x86)\Windows Kits\10\References\Windows.System.SystemManagementContract\2.0.0.0\Windows.System.SystemManagementContract.winmd
#endregion
using System;
using Windows.Foundation.Metadata;
namespace Windows.System
{
[ContractVersion(typeof(SystemManagementContract), 65536)]
[Static(typeof(IShutdownManagerStatics), 65536, "Windows.System.SystemManagementContract")]
[Threading(ThreadingModel.Both)]
public static class ShutdownManager
{
public static void BeginShutdown(ShutdownKind shutdownKind, TimeSpan timeout);
public static void CancelShutdown();
}
}
其中ShutdownKind的枚举类型定义如下:
#region Assembly Windows.System.SystemManagementContract, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null, ContentType=WindowsRuntime
// C:\Program Files (x86)\Windows Kits\10\References\Windows.System.SystemManagementContract\2.0.0.0\Windows.System.SystemManagementContract.winmd
#endregion
using Windows.Foundation.Metadata;
namespace Windows.System
{
[ContractVersion(typeof(SystemManagementContract), 65536)]
public enum ShutdownKind
{
Shutdown = 0,
Restart = 1
}
}
Shutdown就是关机,Restart就是重启。
然而,如果我们要在自己的IoT应用里面调用,会碰到个巨坑。首先,代码是这样的:
private void ShutdownHelper(ShutdownKind kind)
{
ShutdownManager.BeginShutdown(kind, TimeSpan.FromSeconds(0.5));
}
private void BtnRestart_OnClick(object sender, RoutedEventArgs e)
{
ShutdownHelper(ShutdownKind.Restart);
}
private void BtnShutdown_OnClick(object sender, RoutedEventArgs e)
{
ShutdownHelper(ShutdownKind.Shutdown);
}
运行就会爆炸!
抛出异常:没有权限
通常在UWP里,调用没有权限的API会爆炸的解决办法是在应用的manifest文件里勾选对应的权限。然而这个关机和重启,在VS的界面里是没有选项的。我们需要用XML编辑器打开
Package.appxmanifest,然后手工加权限:
在Package节点的属性里加个命名空间
xmlns:iot="http://schemas.microsoft.com/appx/manifest/iot/windows10"
然后再Capabilities节点里加这个:
<iot:Capability Name="systemManagement" />
最后看起来就像是这样:
<?xml version="1.0" encoding="utf-8"?> <Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:iot="http://schemas.microsoft.com/appx/manifest/iot/windows10" IgnorableNamespaces="uap mp"> ... <Capabilities> ... <iot:Capability Name="systemManagement" /> ... </Capabilities> </Package>
现在再运行就OK了……