这个功能必须在“红石-1”(build 14393)以上的系统版中才能使用,运行在一台设备上的应用,可以通过URI来启动另一台设备上的应用。激活远程应用需要以下前提:
系统必须是build 14393或以上版本,UWP应用必须使用14393或以上版本的SDK开发。
被启动的应用应当支持协议激活,比如Cortana的协议URI为:【ms-cortana:】,当然如果是你自己开发的应用,可以自己定义一个协议,名字随便取,不要跟系统的协议或别人的应用冲突就行,比如:【haha:】【zxzx:】等。
必须用同一个Microsoft帐号登录的设备。即同一个MS帐号登录的设备才可以。这个功能得保证一定的安全性,肯定不能让你随便什么设备都能连,那应用就成了木马了。
设置种类没有限制,只要运行“红石”或以上的Windows 10系统就行,包括PC、平板、Hub、手机、xBox、笔记本、Iot、全息虚拟化设备……如果是虚拟机里面装的系统,用MS帐号登录就可以了,只要是Win 10,管你什么设备,都可以耍。
是不是很高大上,下面老周就说说怎么耍,老规矩,还是先来了解一下方法。
我们要用到两个命名空间,你要用的类,就从这两个命名空间里面找就行了,一定要学会用“对象浏览器”窗口。
Windows.System
Windows.System.RemoteSystems
看看名字,Remote System,你都可以猜到七分,肯定和远程调用有关的。
要调用远程设备上的应用,首先得找出这些设备,SDK提供了两种方法来实现。第一种方法比较简单,直接通过设备名来找,调用RemoteSystem.FindByHostNameAsync(HostName)静态方法,指定要查找的设备名,如果找到,就返回一个RemoteSystem实例(可异步等待)。RemoteSystem类封装了远程系统相关的信息,信息量不大,无非就是计算机名,以及一个ID值,这个ID可以用于唯一标识设备。
第二种方法工程量有点大,它是通过创建一个RemoteSystemWatcher对象,然后用这个对象来监视远程设备的连接情况,如果找到设备,会发生RemoteSystemAdded事件,如果某个设备被移除(MS帐号不再登录该设备,并在设备管理网页中移除设备)就会引发RemoteSystemRemoved事件。
要开启监视就调用Start方法,要停止就调用Stop方法。
在创建RemoteSystemWatcher对象时,可以向RemoteSystem.CreateWatcher方法传递若干个过滤器,以确定查找范围。过滤器类都会实现IRemoteSystemFilter接口。
可选的过滤器可以有这些:
RemoteSystemKindFilter:按设备类型来过滤,如桌面、手机、xBox等,这个字符串可以从RemoteSystemKinds类的静态属性中获取。
RemoteSystemDiscoveryTypeFilter:按发现范围来过滤,规则由RemoteSystemDiscoveryType枚举来定义,Any表示不限制范围,Proximal表示通过内网或蓝牙可以连接的范围来找,Cloud是云端记录的设备,就是用MS帐号登录的设备。当然大提前是这些设备都用MS帐号登录并使用中。
RemoteSystemStatusTypeFilter:通过设备的当前状态来过滤,即这个设备当前是否处于可连接状态。
查找到远程设备后,使用RemoteSystem实例创建一个RemoteSystemConnectionRequest实例,因为激活应用的时候要用到。
最后把刚创建的RemoteSystemConnectionRequest实例,连同要启动应用的URI一起传递给RemoteLauncher类的LaunchUriAsync方法就可以启动远程设备上的应用了。
下面,实战一下。
这个示例不复杂,先扫描可用的远程设备(电脑、手机、平板、游戏机通杀),然后选择一个设备,最终启动目标设备上的【计算器】应用。UWP计算器的协议URI为:【calculator:】(不包括【】)。
首先,查找一下设备。
var reqres = await RemoteSystem.RequestAccessAsync(); if (reqres != RemoteSystemAccessStatus.Allowed) { btnLaunch.IsEnabled = false; return; } List<IRemoteSystemFilter> filterList = new List<IRemoteSystemFilter>(); RemoteSystemDiscoveryTypeFilter ft1 = new RemoteSystemDiscoveryTypeFilter(RemoteSystemDiscoveryType.Any); string[] kinds = { RemoteSystemKinds.Desktop, RemoteSystemKinds.Phone, RemoteSystemKinds.Xbox }; RemoteSystemKindFilter ft2 = new RemoteSystemKindFilter(kinds); filterList.Add(ft1); filterList.Add(ft2); watcher = RemoteSystem.CreateWatcher(filterList); watcher.RemoteSystemAdded += RemoteSystem_Added; watcher.RemoteSystemRemoved += RemoteSystem_Removed; watcher.Start();
注意,在做任何查找操作之前,必须先调用RequestAccessAsync方法,确定系统允许你操作才行,否则是白忙一场。
下面代码处理watcher的两个事件。