原文: 分配的访问权限的展台应用:最佳做法
best practices guidance for developing a kiosk app for assigned access.
在 Windows 10 中,你可以使用锁屏框架和分配的访问权限创建展台应用,该应用允许用户与设备上的单个应用进行交互。 本文档介绍了如何实现展台应用,并介绍了最佳做法。所有示例代码都采用 C# 编写,但应该可以轻松地翻译为你选择的语言,因为基础框架是 Windows RT。本文档专为想要为其客户编写展台应用的 OEM 和 ISV 而编写。
条款
术语 | 描述 |
---|---|
分配的访问权限 | 允许系统管理员通过限制公开给设备用户的应用程序入口点来管理用户体验的功能。例如,你可以限制你公司的客户仅使用一个应用,以便将你的电脑用作展台。每当有人使用指定帐户登录时,他们仅能使用该应用。他们不能使用触摸手势、鼠标、键盘或硬件按钮切换应用或关闭应用。他们同样看不到任何应用通知。 |
锁屏界面应用(或锁屏应用) | 利用设置动态壁纸功能或利用新的锁屏可扩展性框架的应用程序。 |
上方锁屏界面应用(或上方锁屏应用) | 锁屏界面应用运行时(例如,桌面锁定时),在其上方启动的应用程序。 |
下方锁屏应用 | 在已解锁的 Windows 上下文中正常运行的应用程序。 |
LockApplicationHost | 允许上方锁屏界面应用请求设备解锁并允许应用进行注册以便在设备开始解锁时收到系统通知的 WinRT 类。 |
视图或应用程序视图 | 每个视图都是应用中的一个独立窗口。应用可以拥有一个主视图,并可根据需要创建多个辅助视图。有关详细信息,请参阅 ApplicationView。 |
在后台
Windows 10 中分配的访问权限可利用新的锁屏框架。当分配的访问权限用户登录时,后台任务将锁定桌面,并且锁屏界面应用将启动,然后运行锁屏上方的展台应用。展台应用实际上作为上方锁屏界面应用运行。
当锁屏框架启动锁屏上方的展台应用时,它将为展台应用创建新的辅助视图,并在新的辅助视图中呈现其所有主视图。
必须在应用程序清单文件中使用 windows.aboveLockScreen 扩展,才能使你的应用显示在“设置”的“分配的访问权限”中。有关应用程序清单的示例,请参阅附录。
最佳做法
保护你的信息
如果展台应用打算以分配的访问权限并且以正常的方式在锁屏上方运行,则你可能需在已解锁的 Windows 上下文中创建一个要在锁屏上方呈现的不同页面和一个用于锁屏下方的页面。这将使你可以在展台模式下避免显示敏感信息,因为展台模式通常意味着匿名访问。下面是你使用两个不同页面时要遵循的步骤,一个用于锁屏下方,一个用于锁屏上方:
- 在 App.xaml.cs 中的 OnLaunched 函数替代内部,尝试在 rootFrame 导航之前获取一个 LockApplicationHost 类的实例。
- 如果调用失败,则展台应用应在锁屏下方正常启动。
- 如果调用成功,则展台应用应在运行于分配的访问权限模式下的锁屏上方启动。你可能希望此版本的展台应用具有一个不同的主页面,以便隐藏敏感信息。
以下示例将演示如何执行此操作。AssignedAccessPage.xaml 已预定义,而且当应用检测到 AssignedAccessPage.xaml 正在上方锁屏模式下运行时,将导航到该页面。因此,普通页面将仅在下方锁屏方案下显示。
你可以使用此方法确定该应用在其生命周期内是否随时都在锁屏界面上运行并相应地做出响应。
using Windows.ApplicationModel.LockScreen;// inside the override OnLaunched function in App.xaml.csif (rootFrame.Content == null) {LockApplicationHost host = LockApplicationHost.GetForCurrentView();if (host == null){// if call to LockApplicationHost is null, this app is running under lock// render MainPage normallyrootFrame.Navigate(typeof(MainPage), e.Arguments);}else{// If LockApplicationHost was successfully obtained// this app is running as a lock screen app, or above lock screen app// render a different page for assigned access use// to avoid showing regular main page to keep secure information saferootFrame.Navigate(typeof(AssignedAccessPage), e.Arguments);} }
多个视图、窗口和线程
请记住,仅主视图或窗口才会在分配的访问权限模式下呈现,但是要呈现在新的辅助视图中。你在应用中创建的任何其他视图将不呈现。请确保你希望用户看到或访问的所有内容都在主窗口中,因为用户无法看到其他视图。
锁屏框架可将展台应用的主视图呈现于新的辅助视图中(它对该应用完全透明)。你不需要手动创建适用于上方锁屏模式的辅助视图,因为锁屏框架会为你创建一个。这意味着你的应用在上方锁屏模式下运行时实际上将有两个视图。当你的应用在分配的访问权限模式下时,在你的主窗口中运行以下代码,以通过查看视图计数和值来确认当前窗口是否为主窗口。
using Windows.ApplicationModel.Core;CoreApplication.GetCurrentView().IsMain //false CoreApplication.Views.Count //2
下面是示例布局。
调度程序
每个视图或窗口都有其自己的调度程序。在分配的访问权限模式下,不应使用 MainView 调度程序,应改为使用 CurrentView 调度程序。
例如,在以下代码示例中,.xaml 页面上有一个“按钮”和一个 TextBlock。向该按钮添加单击事件处理程序。该处理程序会执行一些后台工作,然后更新 TextBlock的文本。在此示例中使用 CoreApplication.MainView.Dispatcher 将导致应用崩溃,因为在分配的访问权限模式下,主窗口不是 MainView,但在辅助视图中呈现。建议你使用 CoreApplication.GetCurrentView.Dispatcher。
using Windows.ApplicationModel.Core; private async void Button_Click(object sender, RoutedEventArgs e) {button.IsEnabled = false;// start a background task and update UI periodically (every 1 second)// using MainView dispatcher in below code will end up with app crash // in assigned access mode, use GetCurrentView().Dispatcher insteadawait CoreApplication.GetCurrentView().Dispatcher.RunAsync(CoreDispatcherPriority.Normal,async () =>{for (int i = 0; i < 60; ++i){// do some background work, here we use Task.Delay to sleepawait Task.Delay(1000);// update UItextBlock1.Text = " " + i.ToString();}button.IsEnabled = true;}); }
添加除分配的访问权限之外的方法
在某些情况下,用于停止应用程序的电源按钮、Esc 按钮或其他按钮可能在键盘上无法启用或不可用。在这些情况下,请提供一种方法来停止分配的访问权限,例如软件键。以下事件处理程序显示了如何通过响应可能由软件键触发的按钮单击事件来停止分配的访问权限模式。
LockApplicationHost^ lockHost = LockApplicationHost::GetForCurrentView();if (lockHost != nullptr){lockHost->RequestUnlock();}
生命周期管理
如果展台应用意外结束,分配的访问权限框架将尝试重新启动它。如果用户具有对键盘的物理访问权限并按下 Ctrl+Alt+Del 显示登录屏幕,将触发“正在解锁”事件。分配的访问权限框架侦听此事件并将尝试终止展台应用。你的展台应用也可以对此事件注册一个处理程序并退出。有关如何执行此操作的示例,请参阅下面的代码。
using Windows.ApplicationModel.LockScreen;public AssignedAccessPage() {this.InitializeComponent();LockApplicationHost lockHost = LockApplicationHost.GetForCurrentView();if (lockHost != null){lockHost.Unlocking += LockHost_Unlocking; } }private void LockHost_Unlocking(LockApplicationHost sender, LockScreenUnlockingEventArgs args) {// save any unsaved work and gracefully exit the appApp.Current.Exit(); }
在用户按下 Ctrl+Alt+Del 并且登录屏幕出现后,可能发生以下两个事项:
- 用户知道分配的访问权限的帐户密码并解锁桌面。分配的访问权限框架将启动、锁定桌面,而且锁屏界面应用也将启动,从而启动展台应用。
- 用户不知道密码,或不会采取任何进一步的操作。登录屏幕将超时,桌面也会重新锁定;锁屏界面应用将启动,从而启动展台应用。
不要在分配的访问权限模式下创建新的窗口或视图
如果在分配的访问权限模式下调用以下函数,则该调用将结束,并带有运行时异常。如果相同的应用(在锁屏下方使用时)调用此函数,则不会导致运行时异常。使用 LockApplicationHost 有助于确定应用的分配的访问权限模式,并相应地对你的应用进行编码,例如,如果应用处于分配的访问权限模式下,则不会创建新的视图。
Windows.ApplicationModel.Core.CoreApplication.CreateNewView(); //causes exception
附录
下面是一个示例应用程序清单,你可以看到 windows.aboveLockScreen UAP 扩展名。必须在你的 Windows 10 通用 Windows 平台 (UWP) 应用中使用此扩展名,以便它在“设置”的“分配的访问权限”应用列表中显示。
<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" IgnorableNamespaces="uap mp"><Identity Name="bd4df68b-dc18-4748-a14e-bc21dac13736" Publisher="CN=chandde" Version="1.0.0.0" /><mp:PhoneIdentity PhoneProductId="bd4df68b-dc18-4748-a14e-bc21dac13736" PhonePublisherId="00000000-0000-0000-0000-000000000000" /><Properties><DisplayName>AboveLock</DisplayName><PublisherDisplayName>chandde</PublisherDisplayName><Logo>Assets\StoreLogo.png</Logo></Properties><Dependencies><TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.0.0" /></Dependencies><Resources><Resource Language="x-generate" /></Resources><Applications><Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="AboveLock.App"><uap:VisualElements DisplayName="AboveLock" Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png" Description="AboveLock" BackgroundColor="transparent"><uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png"></uap:DefaultTile><uap:SplashScreen Image="Assets\SplashScreen.png" /></uap:VisualElements><Extensions><uap:Extension Category="windows.lockScreenCall" /><uap:Extension Category="windows.aboveLockScreen" /></Extensions></Application></Applications><Capabilities><Capability Name="internetClient" /></Capabilities> </Package>