问题来源

文件服务器文件夹操作在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. 项目经验分享——Java常用工具类集合 转

    http://blog.csdn.net/xyw591238/article/details/51678525 写在前面     本文涉及的工具类部分是自己编写,另一部分是在项目里收集的.工具类涉及数 ...

  2. posix第二篇-----linux 锁机制

    1 简介 锁机制(lock) 是多线程编程中最常用的同步机制,用来对多线程间共享的临界区(Critical Section) 进行保护. Pthreads提供了多种锁机制,常见的有: 1) Mutex ...

  3. 一个很好玩的命令:stty

    stty命令修改终端命令行的相关设置.语法stty(选项)(参数)选项-a:以容易阅读的方式打印当前的所有配置:-g:以stty可读方式打印当前的所有配置.参数终端设置:指定终端命令行的设置选项.实例 ...

  4. svn第一篇----入门指南

    摘要:trunk存放的是主代码,不修改,branch,tag,milestone均是从trunk中衍生的.branch复制trunk中代码用于开发,tag用于存放比较重要的发行版,存放release版 ...

  5. photoshop如何快速切图

    作为业余爱好,之前都是用比较笨的方法切图,甚至用裁剪工具一张一张的切. 后来知道用切片工具,但也仅限于互不重叠的图片. 在工作中实际使用时才发现实在是太慢了,慢到上级自己说你不用做了,我来吧. 其实, ...

  6. BZOJ 2209: [Jsoi2011]括号序列 [splay 括号]

    2209: [Jsoi2011]括号序列 Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 1111  Solved: 541[Submit][Statu ...

  7. js生成随机数

    //生成n以内的随机数 function getRandom(n){ return Math.floor(Math.random()*n+1) } //生成1000以内的随机数 alert(getRa ...

  8. mongodb 查询时没有索引报错(too much data for sort() with no index)

    报错信息: .... too much data for sort() with no index.... 给对应排序字段加索引就OK 了... 在对应"表"名上,右键--> ...

  9. thinkphp ,进行关联模型的时候出现的问题,版本是3.2

    看的后盾网络视频,里面操作的是3.1. 我用的是onethink,基于3.2. 在关联模式的操作时.主要是user role  role_user  3个张表 视频中可以操作,但是本地操作出现问题. ...

  10. jmeter+ant+jenkins+mac使用HTML Publisher插件后查看html报告显示不正常

    Jenkins安全默认将以下功能关闭: 1.javascript2.html上的内置插件3.内置css或从其它站的css4.从其它站的图处5.AJAX 报告中有javascript,所以显示异常.解决 ...