2017 年 9 月

第 32 卷,第 9 期

此文章由机器翻译

新式应用 - UWP 应用的协议注册和激活

通过 Frank La La

Frank La Vigne在我最后一列中,我介绍了如何使用启动器类扩展的通用 Windows 平台 (UWP) 应用的功能通过利用内置于 Windows 的其他应用的功能。例如,我是能够添加完备映射功能,如搜索查找比萨的好时机和查找方向的流量报表完成而无需将大大增加复杂性添加到我的应用程序的基本代码。在本月的列中,我将探索的另一端的公式:如何公开到其他应用的 UWP 应用的功能。

当然,以编程方式启动应用程序并将从其他应用程序传递参数沿早于 UWP。事实上,许多 Windows 应用程序支持此操作通过命令行开关。例如,若要启动 Microsoft Word 在安全模式下,其中将禁用外接程序和插件,请传递参数"/ 安全"WinWord.exe 文件。若要测试此项,按 Windows 键 + R,以打开运行对话框。在文本框中,键入"Winword.exe /safe"并单击确定。如果你有在系统上安装的 Microsoft Word,程序将启动在安全模式中。此外,类似命令存在 Excel、 PowerPoint 和其他内容。显然,启动具有参数的程序不是新的机制。但是,最新内容、 是 UWP 提供的附加机制:统一资源标识符 (URI) 激活。

URI 激活

我最后一列中 (msdn.com/magazine/mt784669),我使用 URI 激活启动并将参数传递到多个应用。然后,应用程序采用这些输入的参数,并得到处理它们。例如,若要获取以华盛顿特区和纽约之间驱动方向,与 Windows 10 中的默认映射应用程序,应用程序只需通过以下 URI 到启动器类:

bingmaps:?rtp=adr.Washington,%20DC~adr.New%20York,%20NY&mode=d&trfc=1

或者,在运行对话框框中键入此命令还将产生相同的结果。已注册地图应用来处理"bingmaps"协议。文本后问号表示参数传递到地图应用。在这种情况下,它将设置的开始和结束点,以及一个模式以指示驱动 ("d") 和 1 以将流量数据添加到结果。

如果您希望您的应用程序执行类似的方式? 你将需要采取以便注册协议和处理后续的参数传递给它的步骤有哪些?

第一步是创建新项目。通过从“文件”菜单中选择新项目,在 Visual Studio 中创建新的空白 UWP 项目。展开已安装的模板 |Windows |空白应用 (通用 Windows)。ProtocolActivation 为项目命名,然后单击确定。此后,立即将出现一个对话框,询问你的应用程序应为目标的 Windows 版本。对于此项目,默认选项将是不错,因此只需单击确定。

注册 URI 协议

既然已创建了项目,打开 appmanifest 以注册协议。在解决方案资源管理器,查找 Package.appmanifest 文件,并双击它以将其打开。单击声明选项卡。从下方可用声明下拉列表中选择协议。现在,单击添加将声明添加到清单。屏幕应类似于图 1

添加协议声明 (请注意的验证错误)
图 1 添加的协议声明 (请注意的验证错误)

强烈建议你先为的徽标和显示名称字段中提供条目,尽管唯一的必填的字段是名称。在文本框中输入"bingmaps"。按 Tab 键。请注意,文本框失去焦点后,验证错误会消失。通过按 F5、 从调试菜单上,选择启动调试或只需单击工具栏上的播放图标运行项目。应用程序运行后,按 Windows 键 + R 以启动运行对话框。输入"bingmaps:"的文本框,然后单击确定。请注意默认映射应用像以前一样启动。

这将打开重要注意事项:某些协议不能重写。有关完整列表,是我的上一个列引用或指保留文件并在 URI 方案名称的 MSDN 文档bit.ly/2st28Er。选择任何这些保留的名称不会导致一条错误消息;只需不会被激活应用程序。

注册自定义协议

如果它仍在运行,请关闭应用程序。返回到的清单文件并将名称字段的内容更改为"msdncolors"并保存项目。现在,按 Windows 键 + R 以打开运行对话框中,在文本框中输入"msdncolors"并单击确定。系统级对话框中显示建议中所示查找可以处理此协议的存储区中应用图 2

当系统发现不熟悉协议显示的对话框
图 2 显示当系统发现不熟悉的协议的对话框中

虽然可能已在应用程序的清单文件中声明了该协议,它尚未尚未已在系统上注册。这发生在安装时。现在运行解决方案,然后输入到运行对话框"msdncolors",再一次。同一对话框中将出现,但带有新选项添加: ProtocolActivation 应用程序,如中所示图 3。单击“确定”。ProtocolActivation 应用将启动。关闭应用程序。在运行对话框中再次输入"msdncolors"。此时,不将任何对话框中,是否已选中"始终使用此应用程序"中的选项,将只需运行该应用。

新的应用程序现在显示为选项
图 3 新的应用程序现在显示为选项

处理应用程序激活

UWP 应用可以是激活任意数量的方式,点击其磁贴时或当协议激活由用户启动。为了检测如何启动应用程序,必须重写 OnActivated 事件处理程序。

在解决方案资源管理器,打开 App.xaml.cs 文件中,并将以下代码添加到 App 类:

protected async override void OnActivated(IActivatedEventArgs e)
{
  if (e.Kind == ActivationKind.Protocol)
  {
    var dialog = new MessageDialog("App Activated by Protocol.");
    await dialog.ShowAsync();
  }
  Window.Current.Activate();
}

再次运行该解决方案,打开运行对话框,在键入"msdncolors:",然后单击确定。此时,你将看到消息对话框。停止运行中的应用程序。现在,通过按 Windows 键 + R 中重新打开运行对话框中,输入"msdncolors:"的文本框,然后单击确定。请注意,相同的消息对话框出现时,但应用程序不会继续进行下初始屏幕。原因为何将在以后加以解决。

通过 URI 传递参数

当启动通过 URI 激活应用具有其使用时,实际强大功能中将参数从一个应用程序传递到另一个。这可以通过将参数追加到协议请求。此机制进行操作几乎是相同的 HTTP GET 请求的方式。

例如,Uri 遵循的模式:

[protocol]:[host address]?[parameter1]=[value1]& [parameter2]=[value2]

例如,给定 URI https://bing.com/search?q=data%20driven%20podcast、 的协议为 HTTP,则主机地址是bing.com,和"数据 %20driven %20podcast"的值传递给参数"q"。 请注意在"数据驱动的播客"中的空格都转换为"%20"。 参数名称和 URI 中传递的值必须进行编码。

修改内 OnActivated 方法以包含所做的更改中所示的代码图 4

图 4 修改 OnActivated 方法内的代码

if (e.Kind == ActivationKind.Protocol)
{
  var args = e as ProtocolActivatedEventArgs;
  var message = "no parameters passed";
  if (args.Uri.PathAndQuery != string.Empty)
  {
    var queryString = args.Uri.Query;
    var absolutePath = args.Uri.AbsolutePath;
    message = $"Query String: {queryString}\n AbsolutePath: {absolutePath}";
  }
  var dialog = new MessageDialog(message);
  await dialog.ShowAsync();
}
Window.Current.Activate();

中的代码图 4将 ProtocolActivatedEventArgs 类,提供对多个特定于协议激活方案的属性的访问的 IActivatedEventArgs 参数强制转换。在此实例中,我主要关心的 URI 属性。URI 将包含通过协议激活传递到应用的信息。再次运行该应用,打开运行对话框中,输入"msdncolors:background? 红色"到文本框中,单击确定。同样,应用程序将启动。这一次,但是,消息对话框将具有查询字符串和显示 AbsolutePath 值。

停止应用并从运行对话框中重新运行同一命令。同样,应用程序不会继续进行下初始屏幕。是时候地址。

导航到页面

修改在 App.xaml.cs 中以匹配中的代码的 OnActivated 方法图 5。虽然此代码看起来很复杂,这不实际。很多其他代码问题围绕查找活动窗口的当前内容。在已运行该应用的情况下,此应用程序的当前内容将 MainPage 类。当应用程序未运行,而协议激活由启动时,没有当前的内容,然后 Window.Current.Content 具有 null 值。在这些情况下,代码会创建一个新的框架,设置相应的事件处理程序和内容,并导航到 MainPage。有关的窗口和帧类的详细信息,请参阅bit.ly/2tGwt1Hbit.ly/2sQ8LTY分别。

图 5 更新 OnActivated 代码

protected override void OnActivated(IActivatedEventArgs e)
{
  if (e.Kind == ActivationKind.Protocol)
  {
    var args = e as ProtocolActivatedEventArgs;
    if (args.Uri.PathAndQuery != string.Empty)
    {
      Frame rootFrame = Window.Current.Content as Frame;
      if (rootFrame == null)
      {
        rootFrame = new Frame();
        rootFrame.NavigationFailed += OnNavigationFailed;
        Window.Current.Content = rootFrame;
      }
      if (rootFrame.Content == null)
      {
        if (!rootFrame.Navigate(typeof(MainPage)))
        {
          throw new Exception("Failed to create initial page");
        }
      }
      var fragment = args.Uri.Fragment;
      var absolutePath = args.Uri.AbsolutePath;
      var mainPage = rootFrame.Content as MainPage;
      mainPage.NavigateWithParameters(absolutePath, fragment);
    }
  }
  Window.Current.Activate();
}

代码的其余部分是需要稍做修改从之前,通过添加对 NavigateWithParameters 方法进行调用。这是如何获取 URI 中的信息发送到 MainPage 类。现在是将该方法添加到 MainPage.xaml.cs 文件并将一些 UI 元素添加到 MainPage.xaml 文件的时间。

首先,修改要具有以下 XAML 页面元素中的 MainPage.xaml 文件:

<Grid Name="grdBackground" Background=
  "{ThemeResource ApplicationPageBackgroundThemeBrush}">
  <Grid Name="grdForeground" Width="100" Height="100"></Grid>
</Grid>

这将名称"grdBackground"添加到网格控件已存在,并将添加名为"grdForegound。"内部网格

接下来,添加中的代码图 6到 MainPage.xaml.cs 文件。大多数代码将类似 #FFAA3CC7 ARGB 颜色值的十六进制代码转换到的内容,可以使用 SolidColorBrush。转换代码从博客文章绘制灵感bit.ly/2tGuFFH,其中还包含转换的工作原理的绝佳说明。代码的其余部分是非常简单;它更改一个网格的颜色或其他基于目标参数。

图 6 NavigateWithParameters 方法

public void NavigateWithParameters(string target, string color)
{
  string hexCode = color.Replace("#", string.Empty);
  byte a = (byte)(Convert.ToUInt32(hexCode.Substring(0, 2), 16));
  byte r = (byte)(Convert.ToUInt32(hexCode.Substring(2, 2), 16));
  byte g = (byte)(Convert.ToUInt32(hexCode.Substring(4, 2), 16));
  byte b = (byte)(Convert.ToUInt32(hexCode.Substring(6, 2), 16));

  var brush = new SolidColorBrush(Color.FromArgb(a, r, g, b));

  if (target.ToLower() == "background")
  {
    grdBackground.Background = brush;
  }
  else
  {
    grdForeground.Background = brush;
  }
}

所有的代码在到位后,运行该应用。在运行对话框框中键入"msdncolors:foreground? #FFAA3CC7",然后单击确定。这应启用紫色喜欢的前景网格。现在,键入"msdncolors:background? #FFCFCFCF"到运行对话框的文本框中单击确定。背景网格应变为浅灰色。关闭应用程序。现在,重新输入上述命令以查看尚未运行时确认应用程序相同。

总结

在此列中,我演示了如何注册用于处理特定协议的 UWP 应用。添加此功能将使 UWP 应用能够访问其他应用用户的设备上。这样,其他开发人员创建的应用开发并使你的应用程序更有意义的有趣使用。虽然许多此列中激活已完成使用运行对话框,将相同的 URI 传递给启动器类将产生相同的结果。


Frank La Vigne是在 DataLeader.IO,他可以可帮助客户若要创建更好体系利用技术首席推广员。他是数据驱动 (DataDriven.tv) 的数据科学播客的共同宿主和定期在博客FranksWorld.com

衷心感谢以下技术专家对本文的审阅:Jose Luis 方式


在 MSDN 杂志论坛讨论这篇文章