尝试在Windows NT6+上免驱实现FUSE

作者:V君 发布于:2017-9-22 20:18 Friday 分类:折腾手记

■前言  (这次不是解决问题,因此没有TLDR(´∀((☆ミつ)


首先简单解释一下 FUSE 的定义:

在用户空间实现的虚拟文件系统, 能够让标准文件系统API访问,

只是某个路径在应用程序的控制之下, 还没到达虚拟块设备的级别.


FUSE 能够实现许多有趣的功能, 比如挂载压缩包, FTP, MTP, 甚至 Ramdisk 都能实现.

在 linux 实现 FUSE 可以说是相当容易,

由于 linux 可以把 FUSE 功能集成到内核, 随便 mount 就可以了.

然而 Windows 内核并没有这样的功能,

只能以虚拟设备来创建虚拟盘符或挂载到 NTFS 装入点亦或者建立目录符号链接.

 

现状


在 Windows 实现 FUSE 通常需要虚拟驱动器来实现, 这需要驱动程序来支持.

现成的软件有

1)免费的 WinMount(生死未卜)

2)收费的 NetDrive.

它们都是封装好的产品, 用户不能定制自己的功能.

可以自己实现接口的驱动组件有

1)开源的 Dokan(貌似不太稳定)

2)开源的 WinFsp(没用过,无法评论)

3)死贵死贵的 CBFS.

早些年把玩过Dokan, 虽然提供了.NET的接口, 且实现难度还不算高.

假如接口实现得不稳定, 没妥善处理好异常就可能会引发蓝屏, 这也就是本文的初衷.

-- 不使用驱动来实现 FUSE , 就算接口实现得再糟糕也不会把系统搞崩溃.

 

摸索


稍稍有点经验的 Windows 用户都知道,

资源管理器可以直接访问FTP或多媒体设备存储(MTP/PTP)

可以把路径以文件夹的形式图形化呈现, 

然而这些路径并不能够使用标准文件系统 API 来放访问,

不能用 WindirStat 来统计 MTP 上的文件夹占用情况.

尽管资源管理器双击能打开这些路径中的文件,

其实背地里还是先复制到临时文件再调用关联的应用程序去打开.

 

其实 Windows 还是可以不依赖驱动就能实现 FUSE 的.

目前发现了两种方法, 尽管都是利用网络共享绕一圈, 还蛮折腾的:

1)基于 HTTP 的WebDAV 协议

 在一次折腾如何在安桌手机 USB 的 MTP 模式使用 WinDirstat 的过程中

 发现了 WebDAV 共享 APP.

 安装并启动之后, 按照步骤创建映射盘符, 能被 WinDirstat 访问了.

 咕狗了解到是基于 HTTP 的共享协议.

 (这是WebDAV over WIFI, 这已经和 MTP 没关系了, 不过下文还是会和MTP有关系)

 这才发现 Windows 还有这种共享方式, 支持标准文件系统 API, 

 只是实现机制略坑, 性能略糟糕.

2)Samba 局域网共享

 不解释太多也不会被打 (´∀((☆ミつ

 需要实现一个 SMB 服务端, 还要战 445 端口. 战? 不是占? YES, 稍后娓娓道来.

 

尝(zhe)试(teng)


□WebDAV -- 这货是真FUSE, 只是 Windows 实现机制太坑人


知道这货基于 HTTP 之后, 当然就是去找找看有没有人已经做成类库, 而不是先自己啃RFC.

放狗出去找到两个类库, 分别是 SF 上的 WebDAV.NET 服务框架 和 GitHub 上的 WebDAVSharp.

这次选择了后者, 只要按接口做实现, 就可以达到目的, 咋一看还挺完善的, 只是性能有点慢.

即使用内存来实现后端文件存储, 访问速度也和硬盘差不多,

监视性能才发现, 原来 Windows 在背后依然用临时文件的方式暂存 WebDAV 上面的文件, 

只是重定向了一下文件系统. 难怪这么慢, 这 FUSE 虽然是真货, 但却掺了水.

你可以把它的临时目录(↓)链接到 RAMDISK 以提升性能, 此目录必须存在才能正常操作文件.

C:\Windows\ServiceProfiles\LocalService\AppData\Local\Temp\TfsStore\Tfs_DAV\

只不过这样就失去了用 WebDAV 实现 RAMDISK 的意义, 只能用作简单 FUSE 玩玩.

顺便再贴一个之前还没了过背后原理, 仍未知性能坑时, 实现MTP2DAV

晚些单独写一篇详细介绍的博文. 

 

Samba -- 战445端口要不要太折磨人?


非常幸运地找到最近 TalAloni 用 .net 实现且一直在维护的 Samba 服务端的库 SMBLibrary.

看了下介绍, 确实有提到可以实现虚拟文件系统. -- 只是 445 被 Windows 锁死, 需要一战.

除非禁用 Server 服务, 否则全部适配器的 445 端口将不可用...见爆栈.

尝试了许多诸如增加虚拟适配器的 trick 做法, 然而并没有设么卯月...

停止 Server 服务之后还不行, 445 仍然会被 System 占用, 需要重启...

那就只能彻底禁用了.禁用了 Server 服务并重启之后, 445 端口总算可用.

把内置的目录共享跑起来, 效果还挺理想, 性能相当不错, 看了一下接口并不是很复杂.

就简单做了个后端用内存支撑的 RamDisk 实现, 然而并不是很理想.

-- 非常不稳定, 常规操作下会出现各种错误, 看来是接口适配的不太妥哇...

总之, 这种 Samba 的方式是可行的.

只是稍稍麻烦点, 无论是从禁用 Server 服务还是实现接口上来看...


■结论


WebDAV 可以用来实现简单的 FUSE, 无法考虑性能.可以用 RamDisk 稍稍提升一下.

Samba 性能相当好, 接口略复杂, 目前还没啃透 (´∀((☆ミつ

标签: C# Winform NAS HTTP 传输协议 FUSE VFS Windows

评论(0) 引用(0) 浏览(8)

丢掉花生壳吧!自己实现DDNS

作者:V君 发布于:2017-8-27 23:20 Sunday 分类:我的应用

TL;DR

[源代码] 按需修改,尚未提供直接可用的二进制版本

效果:自动将当前IP地址更新到指定DNS记录,并持续监视确保同步。

用法:

 首次启动应用程序会自动创建数据库,然后因未填入配置而停止运行。

 在数据库填入配置并重新运行即可。

限制:

 目前只实现了 GoDaddy 的域名 API,且需要一个获取当前IP的途径,

 因此没有直接可用的二进制版本。

环境:需要.NET 4.5,兼容 mono

 

不吐不快!

虽然早就知道各种实名制要求的政策出来了,但是没有影响就一直无视。

直到花生壳帐号一个个挂掉,最后到本博客的花生壳也不幸遭到屏蔽,

去花生壳实名认证发现要上传身份证照片以及手持纸条的照片,泥马,这就像x贷一样哇!

如果只是绑定手机号,给你就给你吧,要求不能太过分,再见花生壳!


找别的法子实现 DDNS 吧!

首先想到的是三方DDNS,

比如不存在的 dyndns 啦、无缘无故封帐号的 afraid 啦、没用过的 2233 拉。

纠结这些不靠谱的东西时,灵光一闪:

如果直接把IP通过域名提供商的API捅进去,是不是可以把DDNS搞定?!

赶紧放狗出去找找看可能性,结果就找到了狗爹的API,很全哇!

于是这个小工具就诞生辣!

标签: 我的应用 个人服务器 C# mono DDNS

评论(0) 引用(0) 浏览(59)

使用程序包管理控制台批量安装/更新/修复NuGet包

作者:V君 发布于:2017-8-27 20:24 Sunday 分类:折腾手记

TL;DR

准备好你的 packages.config 配置文件,可以从以前的项目中直接拷贝或自己写。

去程序包管理控制台执行 Update-Package 就能把配文件中的所有包的更新到最新版本。

接下来执行 Update-Package -Reinstall 把配置文件中的包装上。

如果你改变了目标框架,需要重新选择依赖库,可以再次执行 Update-Package -Reinstall。

 

听我扯扯:

在过去新建项目,添加 NuGet 包时只能去包管理器界面一个个手动搜索添加。

当改变了目标框架,只好一个个手动卸载再走一遍上述步骤。 要不要这么麻烦?

依旧喂狗到爆栈,找到批量安装更新全部包的方法,从此再也不需要这么麻烦手动安装了。

标签: 软件开发 VisualStudio

评论(0) 引用(0) 浏览(46)

使用StackStrace获取属性名称的惨痛教训

作者:V君 发布于:2017-7-21 18:04 Friday 分类:折腾手记

TL;DR: 改用 CallerMemberName 的方式.


必须扯,内容再少也要扯!

 

一直以来, 封装配置访问类时, 根据同样的只读属性名称去字典值或查数据库.

尽管比较新的 nameof 关键字可用, 但还是需要重复打字, 这非常不爽.


于是自作聪明的咱就抓取上一个堆栈帧, 取出方法名的方式代替Key.

定义一个无参方法 GetValue ,里面去抓 StackTrace, 

一般情况下, 只读属性的方法名是 get_XXXX, 这种情况直接去掉头就可以吃了.

然后只读属性的 getter 就直接无参调用 GetValue(),

看到一大堆只读属性调用同一个无参方法是不是很魔法啊? 乂目

  public string ConfA => GetValue();
  public string ConfB => GetValue();
  public string ConfC => GetValue(); 


然而, 二般情况出现了... 优化编译并 IL-Repack 之后 --

 只读访问器的堆栈帧不见了!!! EXM?!

错误地取到上一个方法的名字, 导致配置读不出来 囧....

即使在 GetValue 方法加上了 NotInlining 的特性, 问题仍旧存在...

放狗出去找爆栈, 在不太相关的问题上看到有说用 CallerMemberName 可以.

用了之后才知道爽, 问题解决了!

标签: 软件开发 C#

评论(0) 引用(0) 浏览(101)

板载集成网卡问题导致Flash加载失败

作者:V君 发布于:2017-6-23 16:57 Friday 分类:挖坑经验

终更:

关闭中断调整之后用了几天, 问题又出现了, 无论高级选项怎么整都没用.

只好花点钱搞一张独立网卡, 装上之后禁用原来的集成网卡, 问题解决...

推定集成网卡有毛病 _(:з」∠)_


原标题:

莫名其妙:有线网卡驱动设置「中断调整」Interrupt Moderation导致Flash加载失败EXM???


原内容:

TL;DR: 去属性高级,将其关闭,Flash 加载失败的问题解决. 不知道为啥!


点击查看原图



必须扯扯排查过程, 信息量太少了! (´∀((☆ミつ


一个WEB项目测试过程中发现 Flash 上传组件不工作, 右键显示为「影片未加载」.

然后发现只有这台机出现问题, 别的机器都好好的.

不仅上传组件, 所有的在线Flash都受影响.


试着直接在浏览器上输入 swf 的完整 url -- 失败

换IE/FF/360(测试的机器啥都有) -- 统统失败

试着在 Fiddler 中的 Composer 中发出请求, 得到的是超时代替的 504 错误.

最后 telnet 手动发起 HTTP 请求 -- 却能收到响应数据,尽管是一坨乱码,swf 是二进制的嘛!


排除了网络和 Sockets 组件的问题.

这时候只能怀疑是系统里面 Sockets 到浏览器之间出毛病了, 比如 wininet.dll 之类的.

这是没法轻易修复了, 就重装了系统.....


装完之后现象依旧存在, 三脸懵逼.


和重装之前没有变化的只剩下IP了.

由于我们为了方便访问, 设置了固定IP, 试着改一下IP,

居然成功访问了一次, 清除缓存之后又不行了.


只好发挥死马精神, 掏出一个 USB-WiFi 拇指头插上,禁用有线网卡 -- 故障现象消失

反过用有线网卡来能复现故障现象 -- 难道是有线网卡的锅???


抱着疑虑去看看调整MAC地址这类做法能不能打醒, 就去到网卡属性高级了.

眼前一亮, 发现好多奇怪的束手束脚设置, 比如节能啦,调整啦,减负啦 的.

一口气把能关的全部关掉, 然后居然 -- Flash 正常加载了... EXM???


清空缓存, 把配置打回去, 能复现, 这说明问题肯定在某些选项中.

见到「中断调整」这个选项比较不顺眼, 单独关掉之后 -- Flash 加载出来了!

又把它打开,清除缓存 -- 可复现!


于是就懵逼到这里. _(:з」∠)_ (´∀((☆ミつ




标签: 软件开发 软件故障诊断 HTTP Web技术

评论(0) 引用(0) 浏览(177)

Powered by emlog 去你妹的备案 sitemap