這個功能必須在“紅石-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的兩個事件。
private async void RemoteSystem_Removed(RemoteSystemWatcher sender, RemoteSystemRemovedEventArgs args) { await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => { RemoteSystem sys = remoteSystems.FirstOrDefault(r => r.Id == args.RemoteSystemId); if (sys != null) { remoteSystems.Remove(sys); } }); } private async void RemoteSystem_Added(RemoteSystemWatcher sender, RemoteSystemAddedEventArgs args) { await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => { remoteSystems.Add(args.RemoteSystem); }); }
現在,可以在選定的設備上啟動計算器了。
if (lv.SelectedIndex == -1) return; btnLaunch.IsEnabled = false; RemoteSystem rmsys = lv.SelectedItem as RemoteSystem; Uri remoteUri = new Uri("calculator:"); RemoteSystemConnectionRequest request = new RemoteSystemConnectionRequest(rmsys); var r = await RemoteLauncher.LaunchUriAsync(request, remoteUri); btnLaunch.IsEnabled = true;
還有很關鍵一步,就是配置清單文件,如果不配置,是沒有權限的。
支持遠程系統的設備功能是在版本3的XML命名空間中聲明的,所以要先引入。
xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3"
給它一個前綴叫uap3,后面方便引用。然后聲明相關的Capability。
<Capabilities> <Capability Name="internetClient" /> <uap3:Capability Name="remoteSystem" /> </Capabilities>
好了,一切都准備好了,先啟動另一台設備(或者虛擬機中的系統)。
然后回到開發機,運行應用,它會查找到你登錄過的設備。
在列表中選擇一台設備,再點下面的按鈕,如果沒有發生自然災害的話,你的另一台設備上的【計算器】應用就會啟動。如下圖。
好了,今天的話題就討論到這里吧。