问题来源

文件服务器文件夹操作在PC与Surface端确实还是和传统操作一样没什么区别,但是到了手机端与Surface Hub就没那么方便了,因为文件资源管理器Explorer根本没法添加网路硬盘。对于传统行业以及担心云端文件安全的企业固然还是希望能使用文件服务器,特别是SurfaceHub用户。SurfaceHub用户开会的时候会用到很多敏感文件,这个时候如果无法访问内部机密文件服务器,那还有什么用处?

解决方法

由于SurfaceHub只能安装UWP应用,自然首先考虑UWP的实现。目前支持SurfaceHub的应用只有Yuki Explorer与Metro commander,Total Commander暂时不支持。两者也许是使用了以下提到的开源项目SharpCifs??

方法一:文件类型关联(只支持单个用户与Guest用户)

文件服务器文件路径其实就是UNC路径,在StorageFolder说明里面有如下文字:

https://msdn.microsoft.com/zh-cn/windows/uwp/files/file-access-permissions#a-nameaccessing-additional-locationsa访问其他位置

实现:

1,添加权限

2,添加文件类型关联

3,文件服务器文件操作(必须事先将文件服务器的认证信息保存在Window凭据里)

public class ShareFolderService
{
/// <summary>
/// get items from unc path
/// *you must add the
/// </summary>
/// <param name="uncPath"></param>
/// <returns></returns>
public async Task<IReadOnlyList<IStorageItem>> GetShareFolderItemsAsync(string uncPath)
{
var folder = await getFolderFromUncPath(uncPath); return await folder.GetItemsAsync();
} /// <summary>
/// create item to share folder
/// </summary>
/// <param name="uncPath"></param>
/// <param name="name"></param>
/// <param name="isFile"></param>
/// <returns></returns>
public async Task<IStorageItem> ShareFolderCreateItemAsync(string uncPath, string name, bool isFile = true)
{
var shareFolder = await getFolderFromUncPath(uncPath);
if (isFile)
{
return await shareFolder.CreateFileAsync(name, CreationCollisionOption.ReplaceExisting);
}
else
{
return await shareFolder.CreateFolderAsync(name, CreationCollisionOption.OpenIfExists);
}
} private async Task<StorageFolder> getFolderFromUncPath(string uncPath)
{
return await StorageFolder.GetFolderFromPathAsync(uncPath);
}
}

缺点:

  • 用户固定无法自由切换
  • 无法查看全部文件
  • 在SurfaceHub端将导致双击文件无法启动(SurfaceHub Bug)

方法二:SMB协议实现(支持全部用户)

概述:

服务器信息块(SMB)协议是一种IBM协议,用于在计算机间共享文件、打印机、串口等。SMB 协议可以用在因特网的TCP/IP协议之上,也可以用在其它网络协议IPXNetBEUI 之上。

SMB 一种客户机/服务器、请求/响应协议。通过 SMB 协议,客户端应用程序可以在各种网络环境下读、写服务器上的文件,以及对服务器程序提出服务请求。此外通过 SMB 协议,应用程序可以访问远程服务器端的文件、以及打印机、邮件槽(mailslot)、命名管道(named pipe)等资源。

在 TCP/IP 环境下,客户机通过 NetBIOS over TCP/IP(或 NetBEUI/TCP 或 SPX/IPX)连接服务器。一旦连接成功,客户机可发送 SMB 命令到服务器上,从而客户机能够访问共享目录、打开文件、读写文件,以及一切在文件系统上能做的所有事情。

从 Windows 95 开始,Microsoft Windows 操作系统(operating system)都包括了客户机和服务器 SMB 协议支持。Microsoft 为 Internet 提供了 SMB 的开源版本,即通用 Internet 文件系统 (CIFS)。与现有 Internet 应用程序如文件传输协议FTP)相比, CIFS 灵活性更大。对于 UNIX 系统,可使用一种称为 Samba 的共享软件。

Windows的Explorer实现原理如下:

Windows系统本身就是一个SMB服务器,支持版本如下:

除了Windows系统以外,UNIX与Mac或者Android系统都可以安装SMB软件访问各类文件服务器系统的文件。

JAVA开源项目:JCIFS

JCIFS 是一个纯 JAVA 编写的实现 CIFS/SMB 协议的开源项目。它由 samba 组织负责维护开发。 JCIFS 是一个完整的,丰富的,具有可扩展能力且线程安全的客户端库。这一库可以应用于各种 JAVA 虚拟机访问遵循 CIFS/SMB 网络传输协议的网络资源,包括 Windows 下的共享资源和 Linux & Unix 下的 SAMBA 资源。

.NET开源项目:

    • SharpCifs :从JCIFS转换而来,支持Windows Phone 8.1 (Silverlight) 。
    • SharpCifs.Std :从SharpCifs转换而来,支持Xamarin & .NET Core 。Nuget包:Install-Package SharpCifs.Std –Pre

实现:

主要使用SharepCifs.Std来实现。由于SharepCifs.Std类库使用了UWP不支持的包:

  • System.Console (>= 4.3.0)
    System.Threading.Thread (>= 4.3.0)

所有需要将以上两个包做替换处理:

  • System.Console (>= 4.3.0)关联的Console.Error与Console.Write方法替换为StringWriter的Write方法
  • System.Threading.Thread (>= 4.3.0) 替换成Task方法(CurrentThread方法可以为空)
  • Dns.GetHostName()需要替换回SharepCifs的方法

读取文件夹列表:

var folder = new SmbFile("smb://UserName:Password@ServerName/ShareName/Folder/"));
var epocDate = new DateTime(, , , , , , DateTimeKind.Utc);
foreach (var item in folder.ListFiles())
{
var lastModDate = epocDate.AddMilliseconds(item.LastModified()).ToLocalTime();
Log.WriteLine($"Name: {item.GetName()}, isDir?: {item.IsDirectory()}, Date: {lastModDate.ToString("yyyy-MM-dd HH:mm:ss")}");
}

读取文件:

var file = new SmbFile("smb://UserName:Password@ServerName/ShareName/Folder/FileName.txt"));
var readStream = file.GetInputStream();
var buffer = new byte[*];
var memStream = new MemoryStream();
int size;
while ((size = readStream.Read(buffer, , buffer.Length)) > )
memStream.Write(buffer, , size); Log.WriteLine(Encoding.UTF8.GetString(memStream.ToArray()));

创建文件:

var file = new SmbFile("smb://UserName:Password@ServerName/ShareName/Folder/NewFileName.txt"));
file.CreateNewFile();
var writeStream = file.GetOutputStream();
writeStream.Write(Encoding.UTF8.GetBytes("Hello!"));

优点:

  • 由于需要用户名与密码所有支持所有用户(含Guest)
  • 支持所有设备(SurfaceHub,Android,iOS等)
  • 支持所有文件类型

备注:

目前打算将次代码转换为PCL类库,以供在Xamarin项目中实现。

UWP开发技巧:实现SMB协议操作文件服务器文件的更多相关文章

  1. Selenium(八):其他操作元素的方法、冻结界面、弹出对话框、开发技巧

    1. 其他操作元素的方法 之前我们对web元素做的操作主要是:选择元素,然后点击元素或者输入字符串. 还有没有其他的操作了呢?有. 比如:比如鼠标右键点击.双击.移动鼠标到某个元素.鼠标拖拽等. 这些 ...

  2. 通过 SMB 直通优化文件服务器的性能

    https://technet.microsoft.com/zh-cn/library/hh831487.aspx Windows Server 2012 内置新增功能,称为 SMB 直通,用来支持使 ...

  3. UWP开发之控件:用WebView做聊天框

    目录 说明 WebView存在的价值 使用WebView的几个重要技巧 使用WebView做的聊天框 说明 大家都知道,无论是之前的Winform.WPF还是现在的IOS.Android开发中,都存在 ...

  4. Windows10 UWP开发 - 响应式设计

      Windows10 UWP开发 - 响应式设计 本篇随笔与大家简单讨论一下在开发适配不同分辨率.宽高比的Windows10 Universal App布局时的可行方式与小技巧.经验均从实践中总结, ...

  5. HTTP协议开发应用-文件服务器

    HTTP(超文本传输协议)协议是建立在TCP传输协议之上的应用层协议.HTTP是一个属于应用层的面向对象的协议,由于其简捷.快速的方式,适用于分布式超媒体信息系统. 本文将重点介绍如何基于Netty的 ...

  6. 基于SMB协议的共享文件读写 博客分类: Java

    基于SMB协议的共享文件读写 博客分类: Java   一.SMB协议 SMB协议是基于TCP-NETBIOS下的,一般端口使用为139,445. 服务器信息块(SMB)协议是一种IBM协议,用于在计 ...

  7. 基于SMB协议的共享文件读写

    一.SMB协议 SMB协议是基于TCP-NETBIOS下的,一般端口使用为139,445. 服务器信息块(SMB)协议是一种IBM协议,用于在计算机间共享文件.打印机.串口等.SMB 协议可以用在因特 ...

  8. Tornado开发技巧,简单了解tornado

    tornado基础入门(一)——简单了解tornado 参考:http://demo.pythoner.com/itt2zh/ch1.html tornado是一个轻量级的web框架,是一个用pyth ...

  9. SMB协议概述

    一.概述 SMB(Server Message Block)是由微软开发的一种软件程序级的网络传输协议,主要用来使得一个网络上的计算机共享计文件.打印机.串行端口和通讯等资源.它也提供认证的进行进程间 ...

随机推荐

  1. css3盒模型学习--利用box自适应布局

    box-flex是css3新添加的盒子模型属性,它的出现可以解决我们通过N多结构.css实现的布局方式.经典   的一个布局应用就是布局的垂直等高.水平均分.按比例划分. 目前box-flex属性还没 ...

  2. linux undelete

    http://www.tldp.org/HOWTO/archived/Ext2fs-Undeletion-Dir-Struct/index.html http://www.giis.co.in/deb ...

  3. iOS播放gif图方式

    转发:http://www.cnblogs.com/jerehedu/ 图片分为静态和动态两种,图片的格式有很多种,在开发中比较常见的是.png和.jpg的静态图片,但有的时候在App中需要播放动态图 ...

  4. MYSQL管理----数据库删除恢复

    (1) 如果备份了,就好解决了.略. (2)如果日志打开,使用mysqlbinlog来恢复. mysqlbinlog工具的使用,大家可以看MySQL的帮助手册.里面有详细的用, 在这个例子中,重点是- ...

  5. php字符串压缩

    在PHP中偶尔遇到字符串的压缩,比如一个长字符串,数据库开始设计的字段存不下,但是又不想改数据库字段存储长度,就可以用压缩的方式降低数据字段字符串的长度数量级,把几百个字符的字符串压缩到几十个字符.总 ...

  6. 10天学会phpWeChat——第八天:Form类,丰富表单提交的字段类型

    通过前面七讲的系列教程,我们完成了一个包含后台并自适应PC+h5移动端的文章管理模块. 在实际的生产环境中,文章投稿.商品上传等操作并不会简单局限于一个text和textarea组成的表单.在实际中, ...

  7. SSO单点登录设计

    关键字: 单点登录 SSO Session 单点登录在现在的系统架构中广泛存在,他将多个子系统的认证体系打通,实现了一个入口多处使用,而在架构单点登录时,也会遇到一些小问题,在不同的应用环境中可以采用 ...

  8. ubuntu内核的编译安装

    原创声明:转载请注明出处. 一.操作环境: 1.ubuntu版本 2.linux原有内核版本 3.要安装的linux内核版本 linux-3.16.39 二.新内核的编译和安装 1.首先下载linux ...

  9. MVC笔记1

    测试实体类 public class Test { public int id{get;set;} [Required(ErrorMessage="不能为空喔")] [String ...

  10. robotium从入门到放弃 一 测试开发环境搭建

    1.JDK的安装及环境变量的配置    配置JAVA的运行环境,添加完环境变量后,可以打开Windows命令处理程序窗口,通过执行命令java -version验证环境变量是否添加成功.如果添加成功会 ...