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了……