[源码下载]

与众不同 windows phone (38) - 8.0 关联启动: 使用外部程序打开一个文件或URI, 关联指定的文件类型或协议

作者:webabcd

介绍
与众不同 windows phone 8.0 之 关联启动

  • 使用外部程序打开一个文件
  • 使用外部程序打开一个 Uri
  • 关联指定的文件类型
  • 关联指定的协议

示例
1、演示如何使用外部程序打开一个文件
AssociationLaunching/LaunchFile.xaml

<phone:PhoneApplicationPage
x:Class="Demo.AssociationLaunching.LaunchFile"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
mc:Ignorable="d"
shell:SystemTray.IsVisible="True"> <Grid Background="Transparent">
<StackPanel> <TextBlock Name="lblMsg" Margin="0 0 0 10" /> <Button Content="打开一个 .log 文件" Name="btnLaunchFile" Click="btnLaunchFile_Click" /> </StackPanel>
</Grid> </phone:PhoneApplicationPage>

AssociationLaunching/LaunchFile.xaml.cs

/*
* 演示如何使用外部程序打开一个文件
*/ using System;
using System.Windows;
using Microsoft.Phone.Controls;
using Windows.Storage;
using System.IO;
using System.Text; namespace Demo.AssociationLaunching
{
public partial class LaunchFile : PhoneApplicationPage
{
public LaunchFile()
{
InitializeComponent();
} private async void btnLaunchFile_Click(object sender, RoutedEventArgs e)
{
// 在 ApplicationData 的根目录下写一个 myLog.log 文件
StorageFolder applicationFolder = ApplicationData.Current.LocalFolder;
StorageFile storageFile = await applicationFolder.CreateFileAsync("myLog.log", CreationCollisionOption.ReplaceExisting);
using (Stream stream = await storageFile.OpenStreamForWriteAsync())
{
byte[] content = Encoding.UTF8.GetBytes("hello webabcd");
await stream.WriteAsync(content, , content.Length);
} // 启动与 .log 类型文件关联的默认应用程序,来打开指定的文件
Windows.System.Launcher.LaunchFileAsync(storageFile);
}
}
}

2、演示如何使用外部程序打开一个 Uri(自定义协议)
AssociationLaunching/LaunchUri.xaml

<phone:PhoneApplicationPage
x:Class="Demo.AssociationLaunching.LaunchUri"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
mc:Ignorable="d"
shell:SystemTray.IsVisible="True"> <Grid Background="Transparent">
<StackPanel> <TextBlock Name="lblMsg" Margin="0 0 0 10" /> <Button Content="启动一个协议名为 webabcd 的 uri" Name="btnLaunchUri" Click="btnLaunchUri_Click" /> </StackPanel>
</Grid> </phone:PhoneApplicationPage>

AssociationLaunching/LaunchUri.xaml.cs

/*
* 演示如何使用外部程序打开一个 Uri(自定义协议)
*/ using System.Windows;
using Microsoft.Phone.Controls;
using Windows.Networking.Proximity; namespace Demo.AssociationLaunching
{
public partial class LaunchUri : PhoneApplicationPage
{
public LaunchUri()
{
InitializeComponent();
} private void btnLaunchUri_Click(object sender, RoutedEventArgs e)
{
// 使用外部程序打开指定的 Uri(自定义协议,注意这里没有“//”)
Windows.System.Launcher.LaunchUriAsync(new System.Uri("webabcd:hello webabcd")); // nfc 方式启用另一台 wp nfc 设备打开指定的 Uri(需要在 manifest 中声明 ID_CAP_NETWORKING 和 ID_CAP_PROXIMITY)
ProximityDevice nfcDevice = ProximityDevice.GetDefault();
if (nfcDevice != null)
{
long Id = nfcDevice.PublishUriMessage(new System.Uri("webabcd:hello webabcd"));
}
}
}
}

3、演示如何关联指定的文件类型(即用本程序打开指定类型的文件)
AssociationLaunching/FileTypeAssociation.xaml

<phone:PhoneApplicationPage
x:Class="Demo.AssociationLaunching.FileTypeAssociation"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
mc:Ignorable="d"
shell:SystemTray.IsVisible="True"> <Grid Background="Transparent">
<StackPanel> <TextBlock Name="lblMsg" TextWrapping="Wrap" /> <TextBlock TextWrapping="Wrap" Margin="0 10 0 0">
<Run>本程序可以打开 .log 类型的文件</Run>
<LineBreak />
<Run>测试方法:通过 LaunchFile.xaml 打开一个 .log 类型的文件</Run>
</TextBlock> </StackPanel>
</Grid> </phone:PhoneApplicationPage>

AssociationLaunching/FileTypeAssociation.xaml.cs

/*
* 演示如何关联指定的文件类型(即用本程序打开指定类型的文件)
*
*
* 由于配置为 NavUriFragment="fileToken=%s",所以本 app 打开某类型的文件会通过 /FileTypeAssociation?fileToken=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx 启动
* 相关的 UriMapper 参见 MyUriMapper.cs
*
*
* 注:
* 需要在 manifest 中增加类似如下的配置
* <Extensions>
<!--
NavUriFragment="fileToken=%s" 的意思是:
1、某 app 启动外部程序打开 .xxx 文件时会传递文件的 token
2、如果最终是由本 app 打开 .xxx 文件,则本 app 会通过 /FileTypeAssociation?fileToken=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx 启动
-->
<FileTypeAssociation TaskID="_default" Name="myFileTypeAssociation" NavUriFragment="fileToken=%s">
<Logos>
<!--相关类型的文件显示在电子邮件附件中的图标,33x33 像素,其会显示在白色的背景前-->
<Logo Size="small" IsRelative="true">Assets/AppIcon_33x33.png</Logo>
<!--相关类型的文件显示在 Office 中心列表视图中的图标,69x69 像素,其会显示在白色的背景前-->
<Logo Size="medium" IsRelative="true">Assets/AppIcon_69x69.png</Logo>
<!--相关类型的文件显示在浏览器下载中的图标,176x176 像素,其会显示在白色的背景前-->
<Logo Size="large" IsRelative="true">Assets/AppIcon_176x176.png</Logo>
</Logos>
<SupportedFileTypes>
<!--关联的文件类型列表-->
<FileType ContentType="text/plain">.log</FileType>
<FileType ContentType="application/rar">.rar</FileType>
</SupportedFileTypes>
</FileTypeAssociation>
</Extensions>
*/ using System;
using System.Collections.Generic;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Windows.Phone.Storage.SharedAccess;
using Windows.Storage;
using Windows.Storage.Streams;
using System.IO;
using System.Text; namespace Demo.AssociationLaunching
{
public partial class FileTypeAssociation : PhoneApplicationPage
{
public FileTypeAssociation()
{
InitializeComponent();
} protected async override void OnNavigatedTo(NavigationEventArgs e)
{
IDictionary<string, string> queryStrings = this.NavigationContext.QueryString; if (queryStrings.ContainsKey("fileToken"))
{
// 获取需要打开的文件的 token
string fileToken = queryStrings["fileToken"];
// 保存需要打开的文件到本 app 的 ApplicationData
await SharedStorageAccessManager.CopySharedFileAsync(ApplicationData.Current.LocalFolder, "myLog2.log", NameCollisionOption.ReplaceExisting, fileToken);
// 获取文件的文件名称
string fileName = SharedStorageAccessManager.GetSharedFileName(fileToken); lblMsg.Text = "fileName: " + fileName;
lblMsg.Text += Environment.NewLine; // 获取 ApplicationData 中指定的文件
StorageFolder applicationFolder = ApplicationData.Current.LocalFolder;
StorageFile storageFile = await applicationFolder.GetFileAsync("myLog2.log"); // 显示文件内容
IRandomAccessStreamWithContentType accessStream = await storageFile.OpenReadAsync();
using (Stream stream = accessStream.AsStreamForRead((int)accessStream.Size))
{
byte[] content = new byte[stream.Length];
await stream.ReadAsync(content, , (int)stream.Length); lblMsg.Text += Encoding.UTF8.GetString(content, , content.Length);
}
} base.OnNavigatedTo(e);
}
}
}

4、演示如何关联指定的协议(即用本程序处理指定的协议)
AssociationLaunching/ProtocolAssociation.xaml

<phone:PhoneApplicationPage
x:Class="Demo.AssociationLaunching.ProtocolAssociation"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
mc:Ignorable="d"
shell:SystemTray.IsVisible="True"> <Grid Background="Transparent">
<StackPanel> <TextBlock Name="lblMsg" TextWrapping="Wrap" /> <TextBlock TextWrapping="Wrap" Margin="0 10 0 0">
<Run>本程序可以处理 webabcd 协议</Run>
<LineBreak />
<Run>测试方法:通过 LaunchUri 打开一个名为 webabcd 的协议</Run>
</TextBlock> </StackPanel>
</Grid> </phone:PhoneApplicationPage>

AssociationLaunching/ProtocolAssociation.xaml.cs

/*
* 演示如何关联指定的协议(即用本程序处理指定的协议)
*
*
* 由于配置为 NavUriFragment="encodedLaunchUri=%s",所以本 app 打开某协议会通过 /Protocol?encodedLaunchUri=webabcd:xxxxxxxxxx 启动
* 相关的 UriMapper 参见 MyUriMapper.cs
*
*
* 注:
* 需要在 manifest 中增加类似如下的配置
* <Extensions>
<!--
Name 是协议名称,对于本例来说协议的示例为“webabcd:hello webabcd”,注意其没有“//”
-->
<Protocol TaskID="_default" Name="webabcd" NavUriFragment="encodedLaunchUri=%s" />
</Extensions>
*/ using System.Collections.Generic;
using System.Windows.Navigation;
using Microsoft.Phone.Controls; namespace Demo.AssociationLaunching
{
public partial class ProtocolAssociation : PhoneApplicationPage
{
public ProtocolAssociation()
{
InitializeComponent();
} protected override void OnNavigatedTo(NavigationEventArgs e)
{
// 显示协议的详细信息
IDictionary<string, string> queryStrings = this.NavigationContext.QueryString;
if (queryStrings.ContainsKey("protocol"))
{
lblMsg.Text = queryStrings["protocol"];
} base.OnNavigatedTo(e);
}
}
}

自定义 UriMapper,用于处理当本 app 由文件打开或协议打开或镜头扩展打开或图片扩展打开时,导航到相关的处理页面
MyUriMapper.cs

/*
* 自定义 UriMapper,用于处理当本 app 由文件打开或协议打开或镜头扩展打开或图片扩展打开时,导航到相关的处理页面
*
* 注:
* 要使此 UriMapper 有效,需要在 App.xaml.cs 中增加 RootFrame.UriMapper = new Demo.MyUriMapper();
*/ using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Windows.Navigation;
using Windows.Phone.Storage.SharedAccess; namespace Demo
{
public class MyUriMapper : UriMapperBase
{
public override Uri MapUri(Uri uri)
{
string tempUrl = HttpUtility.UrlDecode(uri.ToString()); // 由文件启动本 app 时会通过 /FileTypeAssociation?fileToken=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx 启动
if (tempUrl.StartsWith("/FileTypeAssociation"))
{
// 获取 fileToken
int fileTokenIndex = tempUrl.IndexOf("fileToken=") + ;
string fileToken = tempUrl.Substring(fileTokenIndex); // 获取相关的文件名
string fileName = SharedStorageAccessManager.GetSharedFileName(fileToken); // myLog.log // 获取相关的文件名的扩展名
string fileType = Path.GetExtension(fileName); // 根据文件类型的不同导航到不同的处理页面
switch (fileType)
{
case ".log":
return new Uri("/AssociationLaunching/FileTypeAssociation.xaml?fileToken=" + fileToken, UriKind.Relative);
default:
return new Uri("/MainPage.xaml", UriKind.Relative);
}
}
// 由协议启动本 app 时会通过 /Protocol?encodedLaunchUri=webabcd:xxxxxxxxxx 启动
else if (tempUrl.StartsWith("/Protocol"))
{
// 获取协议的详细信息
int protocolIndex = tempUrl.IndexOf("encodedLaunchUri=") + ;
string protocol = tempUrl.Substring(protocolIndex); // 导航到处理 webabcd 协议的处理页面
return new Uri("/AssociationLaunching/ProtocolAssociation.xaml?protocol=" + protocol, UriKind.Relative);
}
// 由镜头扩展启动本 app 时会通过 /MainPage.xaml?Action=ViewfinderLaunch 启动
else if (tempUrl.Contains("Action=ViewfinderLaunch"))
{
return new Uri("/CameraAndPhoto/LensExtensibility.xaml?fromLens=true", UriKind.Relative);
}
// 由图片扩展之“共享...”启动本 app 时会通过 /MainPage.xaml?Action=ShareContent&FileId={xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} 启动
else if (tempUrl.Contains("Action=ShareContent"))
{
string fileId = tempUrl.Substring(tempUrl.IndexOf("FileId=") + ).Replace("{", "").Replace("}", "");
return new Uri("/CameraAndPhoto/PhotoExtensibility.xaml?type=share&token=" + fileId, UriKind.Relative);
}
// 由图片扩展之“编辑...”启动本 app 时会通过 /MainPage.xaml?Action=EditPhotoContent&FileId={xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} 启动
else if (tempUrl.Contains("Action=EditPhotoContent"))
{
string fileId = tempUrl.Substring(tempUrl.IndexOf("FileId=") + ).Replace("{", "").Replace("}", "");
return new Uri("/CameraAndPhoto/PhotoExtensibility.xaml?type=edit&token=" + fileId, UriKind.Relative);
}
// 由图片扩展之“自动上传”启动本 app 时会通过 /MainPage.xaml?Action=ConfigurePhotosUploadSettings 启动
else if (tempUrl.Contains("Action=ConfigurePhotosUploadSettings"))
{
return new Uri("/CameraAndPhoto/PhotoAutoUpload.xaml?fromConfig=true", UriKind.Relative);
}
// 在锁屏设置界面,如果将本 app 设置为背景提供程序,则锁屏界面上会有一个名为“打开应用”的按钮,点击后会通过 /MainPage.xaml?WallpaperSettings=1 启动本 app
else if (tempUrl.Contains("WallpaperSettings=1"))
{
return new Uri("/Others/LockScreen.xaml?WallpaperSettings=1", UriKind.Relative);
} return uri;
}
}
}

将此 app 的 UriMapper 设置为我们自定义的 UriMapper
App.xaml.cs

private void InitializePhoneApplication()
{
// 设置本 app 的 UriMapper
RootFrame.UriMapper = new Demo.MyUriMapper();
}

OK
[源码下载]

与众不同 windows phone (38) - 8.0 关联启动: 使用外部程序打开一个文件或URI, 关联指定的文件类型或协议的更多相关文章

  1. 重新想象 Windows 8 Store Apps (33) - 关联启动: 使用外部程序打开一个文件或uri, 关联指定的文件类型或协议

    原文:重新想象 Windows 8 Store Apps (33) - 关联启动: 使用外部程序打开一个文件或uri, 关联指定的文件类型或协议 [源码下载] 重新想象 Windows 8 Store ...

  2. 背水一战 Windows 10 (98) - 关联启动: 使用外部程序打开一个文件, 使用外部程序打开一个 Uri

    [源码下载] 背水一战 Windows 10 (98) - 关联启动: 使用外部程序打开一个文件, 使用外部程序打开一个 Uri 作者:webabcd 介绍背水一战 Windows 10 之 关联启动 ...

  3. 与众不同 windows phone (47) - 8.0 其它: 锁屏信息和锁屏背景, 电池状态, 多分辨率, 商店, 内置协议, 快速恢复

    [源码下载] 与众不同 windows phone (47) - 8.0 其它: 锁屏信息和锁屏背景, 电池状态, 多分辨率, 商店, 内置协议, 快速恢复 作者:webabcd 介绍与众不同 win ...

  4. 与众不同 windows phone (37) - 8.0 文件系统: StorageFolder, StorageFile, 通过 Uri 引用文件, 获取 SD 卡中的文件

    [源码下载] 与众不同 windows phone (37) - 8.0 文件系统: StorageFolder, StorageFile, 通过 Uri 引用文件, 获取 SD 卡中的文件 作者:w ...

  5. 与众不同 windows phone (43) - 8.0 相机和照片: 镜头的可扩展性, 图片的可扩展性, 图片的自动上传扩展

    [源码下载] 与众不同 windows phone (43) - 8.0 相机和照片: 镜头的可扩展性, 图片的可扩展性, 图片的自动上传扩展 作者:webabcd 介绍与众不同 windows ph ...

  6. 与众不同 windows phone (46) - 8.0 通信: Socket, 其它

    [源码下载] 与众不同 windows phone (46) - 8.0 通信: Socket, 其它 作者:webabcd 介绍与众不同 windows phone 8.0 之 通信 Socket ...

  7. 与众不同 windows phone (35) - 8.0 新的启动器: ShareMediaTask, SaveAppointmentTask, MapsTask, MapsDirectionsTask, MapDownloaderTask

    [源码下载] 与众不同 windows phone (35) - 8.0 新的启动器: ShareMediaTask, SaveAppointmentTask, MapsTask, MapsDirec ...

  8. 与众不同 windows phone (39) - 8.0 联系人和日历

    [源码下载] 与众不同 windows phone (39) - 8.0 联系人和日历 作者:webabcd 介绍与众不同 windows phone 8.0 之 联系人和日历 自定义联系人存储的增删 ...

  9. 与众不同 windows phone (40) - 8.0 媒体: 音乐中心的新增功能, 图片中心的新增功能, 后台音乐播放的新增功能

    [源码下载] 与众不同 windows phone (40) - 8.0 媒体: 音乐中心的新增功能, 图片中心的新增功能, 后台音乐播放的新增功能 作者:webabcd 介绍与众不同 windows ...

随机推荐

  1. [GraphQL] Use Arguments in a GraphQL Query

    In GraphQL, every field and nested object is able to take in arguments of varying types in order to ...

  2. 《objective-c基础教程》学习笔记(十)—— 内存管理

    本篇博文,将给大家介绍下再Objective-C中如何使用内存管理.一个程序运行的时候,如果不及时的释放没有用的空间内存.那么,程序会越来越臃肿,内存占用量会不断升高.我们在使用的时候,就会感觉很卡, ...

  3. c++算法应用 预备

    章 C + +程序设计 大家好!现在我们将要开始一个穿越" 数据结构.算法和程序" 这个抽象世界的特殊旅程,以解决现实生活中的许多难题.在程序开发过程中通常需要做到如下两点:一是高 ...

  4. 学习之路三十六:SQL知识总结 - [游标||字符串分割]

    好久没有写文章了,今天把前不久项目用到的SQL知识总结一下. 一丶字符串分割 SQL内置函数中是没有Split分割函数的,所以需要自己去实现,不多说,上代码: )) RETURNS @result T ...

  5. dnspod动态域名使用感受

    继花生壳不能用之后,3322也开始不太好用了,首先就是360把所有3322的域名全部判定为危险域名,甚至拦截程序对于3322url的api请求. 所以想把3322换成我们自己的独立域名,但是3322他 ...

  6. UNIX环境高级编程笔记之进程控制

    本章重点介绍了进程控制的几个函数:fork.exec族._exit.wait和waitpid等,主要需要掌握的是父进程和子进程之间的运行机制,怎么处理进程的正常和异常终止.以及怎么让进程执行不同的程序 ...

  7. 注解Annotation 详解(转)

    要深入学习注解,我们就必须能定义自己的注解,并使用注解,在定义自己的注解之前,我们就必须要了解Java为我们提供的元注解和相关定义注解的语法. 元注解: 元注解的作用就是负责注解其他注解.Java5. ...

  8. Application MyTest has not been registered. This is either due to a require() error during initialization or failure to call AppRegistry.registerComponent.

    运行react-native项目时报错. 说明一下:项目本来是好的,再次运行就报错了 解决解决办法倒是有,不过具体什么原因不知道.希望有知道具体原因的童鞋能够补充一下 第一种情况:真的是注册的时候写错 ...

  9. 动态密码卡TOTP算法

    TOTP NET实现:http://googleauthcsharp.codeplex.com/ 引用:http://www.cnblogs.com/wangxin201492/p/5030943.h ...

  10. 如何在mac os中安装gdb及为gdb进行代码签名

    1. 安装gdb GDB作为一个强大的c/c++调试工具,一直是程序猿们的良好伴侣,但转到Mac os才发现竟然没有默认安装,所幸还有强大的homebrew工具: brew install homeb ...