Silverlight获取选择文件的本地物理路径
原创作品,允许转载,转载时请务必以超链接形式标明文章来源 、作者信息和本声明。否则将追究法律责任。
最近在做一个大文件断点续传的控件,有试过纯C#的代码来写,但后来发现是在是太不灵活了,于是考虑使用控件。但在控件开发过程中发现,如何获取上传文件的物理路径是个大问题,因为Silverlight不支持获取客户端路径的,不仅是Silverlight,所有的微软上传控件都不支持获取本地物理路径。于是我就各种查,终于发现有种方法可以获取到文件的信息了。
先看一个例子
1 #region 选择文件 2 private void bt_SelectFile_Click(object sender, RoutedEventArgs e) 3 { 4 OpenFileDialog ofd = new OpenFileDialog(); //初始化 5 ofd.Multiselect = true; //设置可以多选 6 ofd.Filter="请选择文件|‘*’"; //限制文件类型及提示 7 if (ofd.ShowDialog() == true) 8 { 9 foreach (FileInfo file in ofd.Files) 10 { 11 UserFile userFile = new UserFile(); //自定义的文件上传信息类 12 userFile.FileName = file.Name; //获取文件名 13 userFile.FileStream = file.OpenRead(); //以只读的方式打开文件 14 userFile.FilePhysicalpath = file.FullName; //在由受信任的应用程序调用时,获取目录或文件的完全路径名 15 userFile.FileTime = file.LastWriteTime; //在由受信任的应用程序调用时,获取文件的最后修改日期 16 } 17 } 18 } 19 #endregion
事实上,在我们调试的时候会发现,userFile.FilePhysicalpath = file.FullName; userFile.FileTime = file.LastWriteTime; 这两句代码会报错,提示说发现未经调试的异常。这是因为Silverlight在由微软的封装下不允许访问客户端的文件,怎么解决呢?其实很简单,在最新发布的Silverlight5的版本中,微软允许开发者在内部通过提升应用程序的信任度来获取本地文件操作的权限。
右击我们的Silverlight项目的属性,在Silverlight一栏下,我们可以看到
勾选【在浏览器内运行时需要提升的信任】,这样我们就可以操作本地文件啦!
这里需要说明一下在勾选了之后微软做的操作,因为有的时候我们勾选了还是不能获取文件的路径。
当你勾选“在浏览器内运行时需要提升的信任”时,visual studio会做下面几件事情:
1、在silverlight的项目文件(.csproj)中增加内容:<RequireInBrowserElevation>true</RequireInBrowserElevation>
2、在项目的Properties文件夹中增加一个文件:InBrowserSettings.xml。
3、在silverlight的项目文件(.csproj)中增加内容:<InBrowserSettingsFile>Properties/InBrowserSettings.xml</InBrowserSettingsFile>
详细情况请看我的另一篇文章Silverlight控件——如何提升应用程序信任度与问题解决
接下来我们将说明如何部署受信应用,首先,要使受信应用在远程客户机上被访问,必须对xap进行签名。
进入TrustedApp项目属性,转到签名页,勾选“为Xap文件签名”,这里我们将创建一个新的测试证书,以此进行演示,实际项目中可以向证书颁发机构申请信任证书,当然这是需要$的。单击创建新测试证书按钮,在弹出对话框中输入密码,这里设置为test,确定后,Visual Studio将创建一个证书文件,默认保存在项目根目录下。
8 接下来单击“从存储区选择”按钮,在弹出窗口中选择刚才创建的证书
9 在签名页面,单击“更多详细信息”按钮,将会显示证书的详细信息,选择详细信息标签,然后单击“复制到文件”按钮,进入证书导出向导:
进入以下页面后,选择不要导出私钥:
此步骤导出的证书供客户端使用!
10 完成后重新生成解决方案
11 将受信应用部署到IIS,部署与传统ASP.NET应用一样,无需做其他设置。
12 以上基本完成了服务端的设置,接下来对于客户端需要做一些设置,才能在浏览器内运行受信应用
13 首先需要启用浏览器内受信应用权限,这可直接通过修改注册表来完成:
注册表路径:HKEY_LOCAL_MACHINE\Software\Microsoft\Silverlight
值名称:AllowElevatedTrustAppsInBrowser
值类型:DWORD
可用值:不可在浏览器内运行受信应用,设置为0,如果启用设置为1
[注:如果没有在话,右键新建一个]
14 在客户端安装第9步骤导出的证书,在证书文件上单击右键,选择安装,进入证书安装向导,选择存储区时,将证书导入到“受信任的发布者”位置:
15 重复第14步骤,选择存储区时,将证书导入到“受信任的根证书颁发机构”位置。
16 到此,我们即可在此客户端上运行受信应用了(注意下图中的地址已经是非本机地址):
17 但是,必须注意此时的Silverlight是没办法自动更新的,也就是说服务端xap更新后,客户端重新访问时不会去自动下载xap,这显然不符合需求,那该怎么做呢?我们需要在每次生成xap的时候,自动对xap进行时间戳签名。
18 进入到TrustedApp项目属性,选择生成事件:
在后期生成事件命令行中输入以下命令,进行xap的时间戳签名:
1 "C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\signtool.exe" sign /v /f "$(ProjectDir)TrustedApp_1_TemporaryKey.pfx" /p test /t http://timestamp.comodoca.com/authenticode $(TargetName).xap
前面为signtool的全路径,它通常位于所安装的Windows SDK目录下,
/f 后面跟随证书的全路径,以上示例表示当前项目下的TrustedApp_1_TemporaryKey.pfx证书文件,
/p 后面表示证书的密码,
/t 后面跟随一个CA Authenticode Timestamping Service的URL地址,命令最后部分为需要签名的xap文件。
进行此步操作后,每次生成xap文件后,Visual Studio将自动调用次命令进行xap的时间戳签名。这样,客户端重新访问网页时,即可自动下载更新xap。
现在我们就可以在测试的时候获取到文件的路径啦。
好了,我们把项目发出到服务器上面去看看吧,咦?怎么还是获取不到呢?原来这是因为调试的时候是在本地,而发不到服务器上之后,是通过互联网访问的,也就是说,这是一个跨域的行为。聪明的你肯定想到了,对了,我们在编写一个可以跨域访问的脚本就行了撒。其实很简单,看下面
在我们的web项目下建立一个clientaccesspolicy.xml,代码如下:
1 <?xml version="1.0" encoding="utf-8"?> 2 <access-policy> 3 <cross-domain-access> 4 <policy> 5 <allow-from http-request-headers="*"> 6 <domain uri="*"/> 7 </allow-from> 8 <grant-to> 9 <resource path="/" include-subpaths="true"/> 10 </grant-to> 11 </policy> 12 </cross-domain-access> 13 </access-policy>
将 clientaccesspolicy.xml 文件保存到承载该服务的域的根目录中。例如,如果该服务在 http://fabrikam.com 上承载,则文件必须位于 http://fabrikam.com/clientaccesspolicy.xml。
另外再建立一个crossdomain.xml,代码如下:
1 <?xml version="1.0"?> 2 <!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd"> 3 <cross-domain-policy> 4 <allow-http-request-headers-from domain="*" headers="*"/> 5 </cross-domain-policy>
将 crossdomain.xml 文件保存在承载服务的域的根目录中。例如,如果该服务在 http://fabrikam.com 上承载,则文件必须位于 http://fabrikam.com/crossdomain.xml。
详情请看使服务跨域边界可用
现在我们就可以在其他电脑打开网站输入网址,获取到我们本地文件的路径了。