就像系统许多内置应用可以通过URI来启动(如ms-settings-bluetooth:可以打开蓝牙设置页),我们自己开发的应用程序,如果需要的话,可以为应用程序自定义一个协议。应用程序协议在安装时会向操作系统注册,以后就可以直接通过URI来打开应用程序并传递相关的参数。

本篇先介绍一下如何为应用程序注册自定义的协议。

为应用程序注册协议是通过清单文件来完成的,清单文件位于项目中,一般的文件名为“Package.appxmanifest”,在创建应用程序项目时会自动创建该文件。如果你有兴趣的话的,可以把生成的清单文件删了,自己建一个,本质上就是一个XML文件,然后把文件的生成方式设置为AppxManifest就可以了。

在预览版的SDK中只能手动写XML的方式来修改清单文件,相信在正式版发布后,VS会提供一个可视化的清单编辑器,毕竟VS的宗旨是解放生产力、发展生产力嘛。

打开Package.appxmanifest文件后,找到Package / Applications / Application节,Application节点通常就是一个,因为大多数情况下,一个应用包中只有一个应用程序。在Application节点下输入以下XML:

      <Extensions>
<!--配置协议-->
<uap:Extension Category="windows.protocol">
<uap:Protocol Name="emp"/>
</uap:Extension>
</Extensions>

Extensions集合表示应用程序的扩展列表,比如像后台任务、后台音频、文件关联这些都属于应用扩展,Extensions下面可以包含N个Extension元素,而对于UAP应用,一定要用uap命名空间下的Extension元素,即http://schemas.microsoft.com/appx/manifest/uap/windows10命名空间。

Protocol元素表示为应用程序定义的协议,Name特性指定协议的名字。这协议名可以自己定,但不要和系统的内置应用协议冲突就行。其实你也不用去记系统内置有哪些保留协议,只要你指定的协议名有问题,就会报错,那时候你自然会知道了。

本例子中,我注册的协议名为emp,在调用应用程序时,只要执行这样的URI就可以了:emp:?a=b&c=d。

协议名字后面记得跟着一个英文冒号,可以直接emp:就可以,?只是为了表示后那一串的参数,就像Web开发中的URI参数default.aspx?fuckID=366一样。

当应用程序被协议激活后,Application实例的OnActivated方法会被调用,方法有一个参数:实现IActivatedEventArgs接口的类型实例。从方法参数的Kind属性可以判断应用程序是由于什么行为被激活的,因为应用程序不仅仅只有协议可以激活,通过文件关联等方式也可以激活应用程序,所以对Kind属性的判断是必须的。

如果确定Kind属性是ActivationKind.Protocol,就说明应用程序就是通过协议激活的,此时可以将方法参数转换为ProtocolActivatedEventArgs来获取激活的URI。

OnActived方法是虚的,所以其实是在App类中进行重写,然后根据传递过来的URI来做出相应的处理。本例中,分析URI中的参数,并将它们提取出来,显示到ShowDataPage页面上。

URI参数一般是a=2这种用等号连接的键/值对,多项目参数用 & 符号来分隔。那么,怎么把这些参数项分析出来呢,我这里采用正则表达式的方式,提取key = value中的key值和vlaue值,而且它们可以多次出现(多项参数)。比如:

a=2&b=3&c=4

就可以提取出三项参数,并可以用字典数结构来封装:

key= a,  value=2

key= b,  value=3

key=c ,  value = 4

所以正则表达式中使用命名分组的方式就比较好,把参数名定义为key组,参数值为value组。正则如下:

((?<key>[^&=]+)=(?<value>[^&]+))+

?<key>[^&=]+表示参数名,排除&、=两个字符;

?<value>[^&]+表示参数值,排除&字符。

因为&是参数连接符,不能出现在参数名和参数值中,对于参数值,也可以?<value>[^&]*,星号(*)允许出现0次,有可能参数值为空,但参数名肯定至少有一个字符的。

相关的处理代码如下:

        protected override void OnActivated(IActivatedEventArgs args)
{
// 判断激类型
if (args.Kind == ActivationKind.Protocol)
{
ProtocolActivatedEventArgs parg = (ProtocolActivatedEventArgs)args;
// 获取激活URI
Uri activeUri = parg.Uri;
// 获取查询字符串
string qry = activeUri.Query;
// 去掉前面的“?”字符
qry = qry.Replace("?", "");
if (!string.IsNullOrEmpty(qry))
{
// 通过正则表达式来分析参数
System.Text.RegularExpressions.Regex rg = new System.Text.RegularExpressions.Regex("((?<key>[^&=]+)=(?<value>[^&]+))+");
var matches = rg.Matches(qry);
IDictionary<string, string> dicdata = new Dictionary<string, string>();
// 取出已匹配的内容
foreach (Match item in matches)
{
dicdata.Add(item.Groups["key"].Value, WebUtility.UrlDecode(item.Groups["value"].Value));
} // 导航到显示内容的页面
Frame rootFrame = Window.Current.Content as Frame;
if (rootFrame == null)
{
rootFrame = new Frame();
Window.Current.Content = rootFrame;
}
rootFrame.Navigate(typeof(ShowDataPage), dicdata);
}
} Window.Current.Activate();
}

由于URI在调用时可能会做URI编码处理,所以用上UrlDecode方法保险一些。

分析URI得到的内容放到一个字典集合中,并在导航时作为参数传递给ShowDataPage页面,因此在ShowDataPage类中要重写OnNavigatedTo方法,并处理传递进来的参数。

        protected override void OnNavigatedTo(NavigationEventArgs e)
{
IDictionary<string, string> data = e.Parameter as IDictionary<string,string>;
if (data != null)
{
System.Text.StringBuilder strbd = new System.Text.StringBuilder();
foreach (var kv in data)
{
strbd.AppendLine(kv.Key + " : " + kv.Value);
}
tbData.Text = strbd.ToString();
}
}

运行应用程序,可以打开浏览器,在地址栏中输入:emp:?name=小明&age=100&city=重庆,然后按回车。应用程序启动并接收数据。如下图:

好了,本文到此结束。

源码下载:http://files.cnblogs.com/files/tcjiaan/ProtocolApp.zip

【Win 10开发】协议-上篇:自定义应用协议的更多相关文章

  1. Win 10 开发中Adaptive磁贴模板的XML文档结构,Win10 应用开发中自适应Toast通知的XML文档结构

    分享两篇Win 10应用开发的XML文档结构:Win 10 开发中Adaptive磁贴模板的XML文档结构,Win10 应用开发中自适应Toast通知的XML文档结构. Win 10 开发中Adapt ...

  2. 移动网络应用开发中,使用 HTTP 协议比起使用 socket 实现基于 TCP 的自定义协议有哪些优势?

    HTTP 是应用层协议,TCP 是传输层协议(位于应用层之下),放在一起类比并不合适.不过猜测楼主是想对比 “标准 HTTP 协议” 还是 “自定义的协议(基于 TCP Socket)” . 一般来说 ...

  3. TeamTalk自定义IM协议的理解

    一.TeamTalk自定义IM协议 TeamTalk自定义IM协议是一种基于protocol buffer的消息传递协议,protocol buffer可以自定义消息格式.protocol buffe ...

  4. 【Win 10 应用开发】启动远程设备上的应用

    这个功能必须在“红石-1”(build 14393)以上的系统版中才能使用,运行在一台设备上的应用,可以通过URI来启动另一台设备上的应用.激活远程应用需要以下前提: 系统必须是build 14393 ...

  5. Newtonsoft.Json 自定义 解析协议

    在开发web api的时候 遇到一个要把string未赋值默认为null的情况改成默认为空字符串的需求 这种情况就需要自定义json序列话的 解析协议了 Newtonsoft.Json默认的解析协议是 ...

  6. 【Win 10 应用开发】RTM版的UAP项目解剖

    Windows 10 发布后,其实SDK也偷偷地在VS的自定义安装列表中出现了,今天开发人员中心也更新了下载.正式版的SDK在API结构上和以前预览的时候是一样的,只是版本变成10240罢了,所以大家 ...

  7. 【Win 10 应用开发】Toast通知激活应用——前台&后台

    老周最近热衷于讲故事,接下来还是讲故事时间. 有人问我:你上大学的时候,有加入过学生会吗?读大学有没有必要加入学生会? 哎哟,这怎么回答呢,从短期来说,加入学生会有点用,至少可以娱乐一下,运气好的话, ...

  8. 背水一战 Windows 10 (101) - 应用间通信: 通过协议打开指定的 app 并传递数据以及获取返回数据, 将本 app 沙盒内的文件共享给其他 app 使用

    [源码下载] 背水一战 Windows 10 (101) - 应用间通信: 通过协议打开指定的 app 并传递数据以及获取返回数据, 将本 app 沙盒内的文件共享给其他 app 使用 作者:weba ...

  9. Python Web开发最难懂的WSGI协议,到底包含哪些内容?

    原文出处: PythonScientists 我想大部分Python开发者最先接触到的方向是WEB方向(因为总是有开发者希望马上给自己做个博客出来,例如我),既然是WEB,免不了接触到一些WEB框架, ...

随机推荐

  1. SQL执行效率和性能测试方法总结

    对于做管理系统和分析系统的程序员,复杂SQL语句是不可避免的,面对海量数据,有时候经过优化的某一条语句,可以提高执行效率和整体运行性能.如何选择SQL语句,本文提供了两种方法,分别对多条SQL进行量化 ...

  2. Hive 笔记

    DESCRIBE EXTENDED mydb.employees  DESCRIBE EXTENDED mydb.employees DESCRIBE EXTENDED mydb.employees ...

  3. AngularJS中的route可以控制页面元素的改变,使多页面变成一个单页面。。。

    SPA(Single Page Application)指的是通单一页面展示所有功能,通过Ajax动态获取数据然后进行实时渲染,结合CSS3动画模仿原生App交互,然后再进行打包(使用工具把Web应用 ...

  4. html+css笔记

    文档结构 1.html文档结构 ①文档类型声明 严格型(标准模式):    <!DOCTYpE HTML>   HTML5 XHTML 1.0:<!DOCTYpE html pUbL ...

  5. nodejs的实现原理和搭建服务器(动态)

    心得体会    今天是我学习的Node.js的第二天,所谓的node.js其实它是javascript编写的服务器的语言,同时它又是属于后台的框架,是一个开放性的平台. 一.相关理论知识: 我们可以用 ...

  6. Web开发者需养成的好习惯

    Web开发者需养成的8个好习惯 每个行业有着每个行业的标准和一些要求,自己只是一个进入前端领域的小白,但是深刻的知道,习惯很重要,就Web开发分享一下,要养成的一些好的习惯. 优秀的Web开发人员工作 ...

  7. c++ 宏定义声明类,并在类中实现回调

    #include <iostream> #include <windows.h> #include <string> using namespace std; ty ...

  8. 使用pip安装BeautifulSoup4模块

    1.测试是否安装了BeautifulSoup4模块 import bs4 print bs4 执行报错说明没有安装该模块 Traceback (most recent call last): File ...

  9. Vuforia结合Skyshop: Image-Based Lighting Tools & Shaders插件实现真实的光照效果

    Skyshop: Image-Based Lighting Tools & Shaders 插件地址:https://www.assetstore.unity3d.com/en/#!/cont ...

  10. IPC操作时IPC_CREAT和IPC_EXCL选项的说明

    IPC(包括消息队列,共享内存,信号量)的xxxget()创建操作时,可以指定IPC_CREAT和IPC_EXCL选项.以共享内存为例:当只有IPC_CREAT选项打开时,不管是否已存在该块共享内存, ...