ThinkPad 蓝牙鼠标偶尔没反应似乎是蓝牙模块的问题

买T430s的时候一起买了个蓝牙小黑鼠, 不过从那个时候开始鼠标就会偶尔在使用中突然没了反应, 需要几次开关蓝牙才能解决, 偶尔运气不好则需要重启电脑. 但是久了就习惯了.

不过前些天蓝牙直接罢工, 一开始我以为重启下就好, 但当时懒得重启于是随便插上了个有线鼠标继续用了几天. 不过当我下定决心重启之后, 发现蓝牙直接从设备管理器中消失了囧. ThinkPad的Radios面板里也看不到蓝牙的开关了. 多次重启无果后猜测是蓝牙模块坏掉了… 不过据说那东西不可能坏…

问了下卖家推荐说是重装系统试试, 笑呵呵,,, 我宁愿把电脑拆个遍也不会重装系统… 太麻烦了. (因为毕竟是被误判到了技术党一类里的人, 电脑里很多工具软件安起来太费神了) 于是, 我选择了把电脑拆个遍… 淘宝入手原装蓝牙4.0模块, 一边看教程一边拆本子. 原来也偶尔会拆本子但不会拆那么深入(主板弄下来了)… 顺道也把风扇清洗了下. 装回去的时候有点小插曲, 因为一颗主板上的螺丝上错, 又在只剩几个的时候才发现有问题, 基本又拆了个通透才搞定…

完成之后开机, 提示设备改动需要重启(可能是因为本子是休眠而不是关机, 蓝牙模块可能也不是即插即用的), 但之后在设备管理器中仍然看不到蓝牙模块,,, 心凉了一大半… 不过打开ThinkPad的Radios面板, 蓝牙开关出现了, 打开, 本子就自动装好驱动. 配对完鼠标后, 一切正常. 使用了小两天之后, 鼠标都没有再出现之前突然瘫痪的情况, 粗略猜测是之前的蓝牙模块一直有问题,,, 只是前几天终于爆发了.

顺便ThinkPad T430s的拆机过程也比较伤心, 网上有拆机的照片, 但是没说步骤, 我也是第一次拆那么多… 简单说下步骤便于需要的同学参考, 中间可能需要自己整理下线, 也请大致记一下各种螺丝的位置.

1. 电池, UltraBay, 还有盖住内存网卡等等的那块板子.
2. 卸下后盖上, 及拆开上面那个板子内所有能看到的螺丝(除了固定网卡/SSD这类的, 不过如果想卸下主板也需要拆). 其中有两颗是固定键盘的, 在本子背部都会有小图片和箭头提示.
3. 卸下硬盘盖子, 电脑正常防止时在左手手掌的位置. 卸下螺丝后抠螺丝在的那一边就可以打开了. 卸下硬盘和可以看到的螺丝.
4. 拆键盘, 这个需要注意, 在拆掉上述所说的固定键盘的螺丝后, 把键盘向上推, 然后先掀开键盘下方, 再取出键盘. 注意排线(我的没有键盘背光灯, 所以只有一根, 估计有键盘背光的会有两根).
5. 拆掉这面能看到的所有跟固定C面(也就是本子键盘那面)的螺丝, 这个时候应该就能取下C面了. 蓝牙模块就在右下角UltraBay下面, 非常小.
6. 如果想继续拆下主板, 需要先拆下显示器. 在本子后侧面有两个正方形的小贴片挡住了螺丝, 用刀背小心撬开, 卸下螺丝即可. 另外还有和主板相连的几块小东西, 需要先卸下. 有一块有一颗螺丝挡在排线下面, 需要掀开排线卸下.

大致就是这样了, 再提醒下一定注意记各种螺丝的位置啊…

附图两张~

WP_20130421_002

WP_20130421_012

ThinkPad T430s 加装 128G mSATA SSD, 重启变成了一种享受

上学期期末本来打算入手 Lumia 920, 但是 9 月份预定之后, 到年底都没有发货, 便退了款另外凑钱入了台低配的 T430s 水货 (i5-3210M/NVS 5200M/4G DDR3-1600/320G/1600×900). 买回来之后就加了 4G 内存. 因为自己比较喜欢开一堆程序不管, 经常任务栏都是堆满的状态… 虽然是低配, 但是比起两年前的 SL410, 也好太多了.

配上寝室小隔间的背景.

tp-1

ThinkPad T430s + Lumia 800 + ThinkPad SL410

tp-2

前些时候就一直计划着买个 SSD, 本来想买 256G 的, 但想着还是节约点, 128G 应该大概够用了. 淘宝 700 大洋入手 镁光 M4 CT128M4SSD3, mSATA 6Gb/s, 但后来发现本子本身的 mSATA 接口是 SATA 2, 达不到这个速度. 所以实际读取速度也就是 250MB/s 的水平. 另外话说 mSATA 的 SSD 实际大小比我想象中小很多, 貌似只有 3 x 5 cm.

ssd-1

本来指望 WEI (Windows 体验指数) 的主硬盘分能跑满 7.9,,, 结果只得了 7.8, 略伤心.

wei

但不管分数如何, 加装 SSD 之后, 本子的使用体验直线上升, 我把 下载/图片/视频 这三个库放到了原来的机械硬盘中, 其他东西留在 SSD 上. 开机到桌面显示的时间明显变短, 大约只有十几秒. 但这还不是最爽的, 最爽的是从桌面显示之后开机自动启动的程序几秒钟之内全部加载完成, 很快本子就进入了完全可用的状态. 当然, 应用程序启动什么的, 速度也没得说, VS 的启动和解决方案加载也变得非常惬意.

ssd-2

最后, 觉得大家要是手里有这几百块闲钱, 也可以考虑入手一个!

使用 Visual Studio 内建的 WebDev.WebHost.dll 搭建轻量级 .NET 服务器

最近做的 X-Wall, 偶尔需要和浏览器进行交互, 之前采取的办法是注册一个 xwall 协议, 然后浏览器中用 JavaScript 通过改变 location.href 的方法调用. 但是有两个缺点, 一个是第一次很多浏览器会有提示, 另一个是只能触发不能得到结果, 也就没法知道操作是否完成.

后来在网上搜索相关解决方案, 看到了这个 <重编译WebDev.WebServer,使其支持网络应用>.  觉得有戏, 就也反编译了下 VS 2012 自带的看了看. VS 2012 里有其实有两个, 一个是 WebDev.WebHost20.dll, 一个是 WebDev.WebHost40.dll, 因为统一用 .NET 3.5, 所以就选择了第一个. 不过与上面所引用的文章目的不同, 我是希望这个东西作为程序内建的微型服务器, 而不是作为一个单纯的程序, 所以只需要这个 DLL 就可以了. 不过也用上了文章作者添加的 InitHost 方法, 用于初始化.

在 Windows 7 下面没法直接看到这个文件, 可以打开资源管理器后直接在搜索栏搜索 WebDev.WebHost, 或者借助 WinRAR 在 Windows\assembly\ 目录下找到复制出来, 然后用 Reflector 反编译. 修改后在项目中添加引用, 调用方式:

// path 是 ASP.NET 程序目录, port 和 vpath 对应 URL 中的位置如下.
// localhost:[port]/[vpath]/
var server = new Microsoft.VisualStudio.WebHost.Server(port, vpath, path);
server.Start();

除了第一次访问还是略慢, 其他都蛮好. 希望有用~

应用程序自动升级解决方案 (.NET/非.NET都适用)

所以每次做了东西都会有话想说.

原来做 Pacgen (PAC file GENerator) 的时候, 为了实现自动升级, 专门写了个叫 Updative 的命令行工具 (当然还有个给程序用的 DLL), 会比对每一个文件的版本, 并且生成一个目录文件, 这样软件升级的时候就只需要下载更新的文件. 当时做得还是蛮有意思的. 可惜后来想做得更强大, 反倒把逻辑搞混了, 于是不了了之.

最近重写了 Pacgen, 并且因为不再使用 PAC 文件, 而是用 Privoxy 自带的 filter, 再叫 PACgen 也不大说得过去, 便改名 X-Wall, 也更直观. (欲知详情, 请访问 http://x-wall.org/)

所以怎么解决这个自动升级的问题呢? 网上其实有不少现成的类库, 不过我是个怕麻烦的人, 所以懒得去看文档… 我是使用的 Inno Setup 打包的程序. 所以一开始只是给程序提供了简单的版本检查, 下载新的安装包, 并且执行. 之后由用户手动完成. 因为安装包会记住用户之前的设置, 所以实际上这个过程除了多点几下下一步, 也没什么太大的不好.

所以整个流程便是, 启动安装包, 退出程序, 安装后再启动.

但说来我也知道 Inno Setup 有些命令很久了, 就是没联系到一起. 不过还好在有生之年这一天终于是出现了. 改动几行代码, 下载之后启动安装包时加上 /silent 开关, 便大功告成啦.

这里需要 Inno Setup 的相关配置文件添加上安装完成后启动的选项, 并且不能设置为在 silent 模式下禁用.

虽然这样一来, 每次更新都会更新全部文件, 但对于小工具来说, 文件大小还是非常能接受的. 加上我是把东西都放在 Github 上 (详情可以查看我的前一篇文章, 让 Github 成为免费的软件发布/下载/更新的服务器), 速度也不错.

让 Github 成为免费的软件发布/下载/更新的服务器

这年头, 自己动手丰衣足食, 不过真的做出来个什么好家伙, 要想分享给别人, 也得在网上找个地儿. 之前一直是拿博客的空间来放东西, 不过老实说 FTP 还真不够方便, 而且可能很多人还没有这么个空间, 囧.

后来知道有 Github 这个东西, 再后来发现 Github 有 raw (原始文件) 这个东西, 再后来发现 Github 还有 Github Pages 这个东西. 但 Github Pages 则是后话了.

raw 的路径是固定的, 并且非常规范, 同时有 SSL 加密. 比如 X-Wall 的安装文件我提供的下载地址就是 https://raw.github.com/vilic/x-wall/master/release/x-wall-setup.exe, 从前至后依次是 https://raw.github.com/用户/仓库/分支/目录. 人可以通过浏览器下载, 软件当然也可以通过 GET 拿到, 于是这里的下载和更新就解决啦.

顺便就提提 Visual Studio 提供的 ClickOnce 解决方案. ClickOnce 是个非常方便的东西, 特别是对于小工具来讲. 但也有很多局限性, 其中一些可以通过不那么优雅的方式解决 (比如自动启动, 因为如果直接把 exe 添加到启动目录, 是没法读到正确的设置文件的, 还有 Command Line 传递参数等问题), 另一些则比较… 比如每次升级之后, exe 文件的目录也变了 (其实相当于是新下载到了另一个文件夹), 防火墙/托盘图标之类的设置也就没了. 最近做的 X-Wall 也是因为这点最后放弃了 ClickOnce.

对于 ClickOnce 来说, 设置自动更新都是傻瓜化的, 这个蛮好, 所以图方便的话, 还是不错的选择. 而这里要说的是, 我们也可以将 ClickOnce 的应用部署到 Github 上. 不过多年前当作者第一次尝试这么做的时候, 结局是悲惨的. 因为 ClickOnce 有签名, 所以要保证提交的文件和签名是一致的. Git 默认安装提交的时候貌似会把 Windows 风格的换行变成 Linux 风格, 这个就是问题的原因了. 重新运行安装程序 (也许可以直接通过命令改, 但作者是懒人), 选择 “Commit as-is” 的选项.

之后, 把 ClickOnce 的应用发布到本地文件系统上, 也就是你的 Git 仓库所在的文件夹. 其实我们可以新建一个分支来专门放这些东西, 这个还是用 Github Pages 的时候学到的. 这个时候, ClickOnce 的自动更新设置中, 把地址设置成本地发布的这个文件夹提交到 Github 之后 raw 对应的目录即可. 最后提交代码, 大功告成.

最后再提一下 Github Pages. 当然你可以用来做个人/组织/项目的页面, 或许也可以用来做软件的下载/升级服务器. 之前说的 raw 上用户可以下载 exe 等等 binary 的文件, 软件也可以检查并下载更新, 唯有个缺点就是 MIME 类型有时候不那么尽如人意. 比如 js 也好, xml 也好, 都是 plain/text. 但用 Github Pages 理论上来讲就可以避免这个情况了. 总体来说, 如果你不嫌麻烦那么一点点, 并且不需要 SSL 加密连接的话, 用 Github Pages 做这个事情或许会更好.

另外 X-Wall 的主页也是架设在 Github 上的, 欢迎访问! http://x-wall.org/

吐槽下Windows 8, 及其周边

个人来讲, 虽然算不上fan, 还是比较喜欢微软的. 当然因为环境原因, 我也是用着Windows长大的, 最爱的自然是Windows 7.

我是个 “外貌党”. 对外观有特别多的要求, 比如只穿蓝/白两色的衣服/鞋子, 最多能忍受下浅灰色, 但也必须只能是出现在边角. 就连同是蓝色的, 我也常常穿上后发现色调不搭, 比如一个蓝色偏紫, 一个偏绿, 又换下来…

所以即使Linux再好(当然对于我的使用习惯和范围来讲, 它也不是最佳选择), 我也不可能用Linux… UI一项就直接把它刷下去了. 但Windows 7却非常漂亮. 尤其喜欢Aero特效. 如果实在要挑一点美中不足的, 就是Start键的颜色不会随主题颜色变化而变化, 有时候显得有点不协调.

但美的标准显然不止一个, 微软拥有, 至少曾经拥有非常棒的UI设计师, 如果说Aero作为华丽的美征服了我, 那Metro则是因为其简约的美让我着迷.

在第一代WP的尾声, 11年夏天的时候, 入手了我的第一台WP手机, Omnia 7(不过无力吐槽后盖, 为什么要偏棕色!). 当然, 蓝色主题没的说. 再后来, Lumia 800出现, 于是今年年初狠下心购入一台黑色800. 花了两倍于当时买O7的价钱… 但还是爱不释手. 为什么不买蓝色? 因为那个蓝色的色调太飘, 跟我的衣服配不上… (眼睛不那么bitch要死啊…)

所以Windows 7和Windows Phone 7.5, 在我看来是微软在UI上的巅峰作品, 同在这个巅峰上的还有诸如Office 2010, Visual Studio 2010.

当然众所周知的, Windows 8来了, 随之而来的还有Office 2013, Visual Studio 2012, 以及Windows Phone 8. 功能上来讲, Office, VS以及WP应该都算是稳步提升, 特别是Visual Studio 2012的JavaScript智能提示相当做得相当出色. 前面我也提到, 我非常喜欢Metro UI, 但…

Windows 8你能不能抓住当年WP Metro UI的精髓啊!!! 精髓不止是方格子好吧!!!

虽然在Windows 8正式发布后我没有使用过(因为换回Windows 7了), 但之前的Developer Preview, Customer Preview, 以及RTM版本我都是一路用过来的, 也用了比较长的时间. 老实说在我这个没有触屏的笔记本上我没有感觉到多大的便利, 也是长期使用桌面. 可惜的是, 我很常用的开始菜单没有了, 开始菜单上的Jump List自然也就没了(当然任务栏上还有). 那些入门级用户不用开始菜单不代表我们这些相对老练的用户不用好吧微软!!! 当然多数功能还是可以在开始屏幕实现, 但我就想启动个程序, 全屏换过去换过来别不别扭啊!!! 总体来讲, 我觉得易用性下降了.

接下来要吐槽Windows 8的UI了, 去其精华取其糟粕非Windows 8莫属啊! 当年看到微软Tellme的宣传片, 那个平板上的UI多舒服啊! 干嘛要被Windows 8整成这样啊!!! 拿那么多颜色来干嘛啊!!! 眼睛不花啊!!! 我只想要蓝色的Tile啊, 蓝色的啊!!! 而且自带的软件Tile颜色也花花绿绿的啊, 是干什么啊这是!!! 你们UI设计师干嘛去了啊!!! 退一万步说, 即使要弄多点颜色请搭配合理好不啊!!! 全是些奇葩的颜色啊!!! 你妹Tile的背景色还是带渐变的啊!!! Metro你搞神马渐变啊!!! 开始屏幕背景一个二个丑到爆啊!!! 不能给个纯黑的选项啊!!! 给个纯黑的要死啊!!!

另外桌面UI做了调整跟Metro统一, 这个我不反对啊, 关键是能不能稍微用点心, 做得好看点和谐点啊!!! 那个进度条就是个三流水准的设计师做得啊!!! 好多Aero风格的图标一个没换啊!!! 花得了多少时间啊!!!

我是打算坚守在Windows 7上再熬一段时间了,,, 最多装个双系统,,, 为了Windows Phone 8开发. 但是啊!!! Visual Studio 2012那么爽能不能出个2010风格的皮肤啊!!! 虽然2012不丑, 但是跟我的Windows 7不怎么搭啊!!! Office到还将就, 毕竟2010我也够用了.

顺便Windows Phone 8… 开始屏幕可以添加更小的Tile, 这个我觉得挺好的, 但配色能不能不要那么奇葩啊!!! 不过还好没有Windows 8乱. 至少多数Tile还能是同一个颜色. 不过WP7.5那个XBox的绿色Tile颜色多么和谐啊!!! WP8你干嘛要换成那种屎绿色啊!!! 真心觉得8系列都喜欢用屎色啊… 另外WP7开始屏幕右边的黑边很有感觉, WP8没了, 不过这个还算可以理解…

不过还是因为大爱Metro, 虽然Windows 8不准备升, WP8还是准备入的, 淘宝上预定了Lumia 920… 不过能不能出个小点的啊!!! 800那个大小多舒服啊!!! 或者4.0我也能够忍受啊,,, 一下就来个4.5让我情何以堪啊, 还180+g的重量啊!!! 不过看在其他还不错的份上我就忍了…

希望Windows 9团队里能重新出现优秀的UI设计师… 至少要考虑到我们这些有强迫症的人啊… 顺便我强迫症也不是很强迫好嘛…

现在好纠结好纠结, 强迫症的一方面要让我用最新的系统, 一方面要让我用最漂亮的UI,,, 哎… 不过UI最终还是胜了.

吐槽完了.

VEJIS 0.5 JavaScript 强类型编程新体验!

之前分别提到过Visual Studio 2012强大的JavaScript intellisense, 还有微软的新语言TypeScript. 测试完VS 2012 for Web增加的关于JS提示的新特性之后, 也说过要为此开发一个全新版本的VEJIS及其配套的提示文件, 现在终于算是基本搞定了. 而智能提示能够达到的程度我觉得完全可以媲美一些强类型的语言.

新版本的VEJIS相对0.4又有了不少提升, 重写了整个函数重载的代码, 使得扩展更加容易. 并且在0.4的option_(0.5改为opt_), params_的基础上进行完善. 有点小遗憾是重写的时候又把类模板忘记了, 所以后来发现要支持那东西也不简单, 可能会在下一次重写的时候实现. 不过类的话, 自从0.3开始变动就不怎么大了. 这次在0.5中则是添加了对接口(interface_)的支持, 并提供了两个新的创建特殊类型的函数nul_和delegate_.

模块(module_)部分的话, 主要是增加了对拆分一个模块到几个文件的支持, 并且丢掉了之前use_和module_连缀的写法, 以简化程序结构.

从自己写一些项目使用VEJIS 0.4的经验来看, 还是很惬意的. 以后我也会有一个更好的选择, 当然就是0.5了. 感兴趣的同学可以去VEJIS的网站看看. 现在只写了英文版, 空了之后会出中文.

http://vejis.org

关于 "动态" 模板的憧憬

大概是一年多以前还在一淘实习的时候, 萌生了这么个想法, 如果一个模板可以是基数据驱动的, 那能胜任的工作就从现在更多的格式化字符串和其他一些简单的东西变得更加复杂和强大. 当然因为是数据驱动的, 在写这样一个模板时, 也将体会到数据驱动带来的逻辑上的优势. 不过也是因为各种原因, 当时做完第一步的模板解析之后, 就没再继续了. 因为要做好, 略微困难, 而且不像原来做Prever什么的时候, 虽然代码总量大, 但可以分开成很多小块, 今天断开一点, 明天稍微回想下继续写就好.

除此之外, 另外一个数据驱动的小库, Drop(未更新), 倒是做了出来, 虽然还有诸多不完善, 到最后肯定也免不了被重写的命运… 但就实践来看, 这种方式的确是很实用的.

那回归可能会基于Drop(顺便Drop最近的版本是基于VEJIS的)之上的这个模板系统, 之前取名叫Sonne, 以后多半也是这个名字吧. 前些时候了解了下lisp语言, 才发现它和lisp之间还有一点点相似之处. 这里贴一段很久很久以前写的示例.

<!-- comments -->
{header
    <img src="xxx.jpg" />
    <h1>{title}</h1>
    <p><span>{tip}</span><span>{tip}</span>{description}</p>
}
{nav
    <ul>
    {items[]
        <li>
        {#link {
            {@hash page}
            {@value home}
            {@inner {home}}
            {@class nav-link}
        }}
        </li>
    }
    </ul>
    {#if {
        {@if {#cookies loggedin}}
        {@then <a href="#logout">log out</a>}
        {@else <a href="#login">log in</a>}
    }}
}
{content
    <div>
    {#async {
        {@type html}
        {@url content.ashx?page={#hash { {@name page} {@default home} }}}
        {@loading
            loading...
        }
        {@loaded {data}}
    }}
    </div>
}
{sidebar
    <div>
    {#async {
        {@type json}
        {@url sidebar.ashx?page={#hash { {@name page} {@default home} }}}
        {@loaded
            {data
            <ul>
                {list[]
                <li>{text}</li>
                }
            </ul>
            }
        }
    }}
    </div>
}

还是大概能看出来吧? 大括号开始, 紧接一个字母的, 是闭包, 在里面可以直接书写文本内容. #号开头的则是组件(当然, 你可以定义自己的组件), 里面的@开头的是属性, 也可以理解成参数. 包括if都是以组件的形式存在的, 所以这种一般性让Sonne具有更强的扩展性. 好吧其实, 还有个原因是我实现起来会相对容易, 不用处理更多的特殊化的语法… 😛

再以#async组件为例, 可以看到url属性对应的字符串中存在另一个组件, 所以实际上, 组件是有 “返回值” 的, 可以是字符串, 也可以是文档片段. 因为是数据驱动, 当数据发生变动的时候, #async组件所管理的文档片段也就随之变化了, 并且因为是组件, 也可以很容易地实现定时更新数据.

当时一直期望这东西能改变Web开发的某个分支, 其实现在也有这个想法, 但也不知道最后能不能做出来… 记得后来看到过某个库, 也有类似的功能, 但印象里并没有Sonne强大,,, 具体哪里没有… 忘记了…

TypeScript 小感

今天在一个Windows Phone的论坛看到微软出了个TypeScript, 瞬间想到高中时期自己构想的InviScript和Prever 2… 不过后来因为种种原因, InviScript只是停留在了构想上, 而Prever 2也在开发初期流产. 不过后来取代InviScript的, 则是VEJIS.

很高兴的是, 自己, 当然也一定是很多当时和我面临同样问题的人的设想, 最后被很好的实现. 其实Google也有一个叫Dart的语言, 不过与和InviScript的相似度赶TypeScript和InviScript的相似度就差太多了… 而且我个人也不喜欢Dart的语法, 感觉抛弃了很多JavaScript的精髓.

TypeScript和InviScript应该说都是JavaScript的超集, 并且相同的, 最终都会编译成JavaScript. 这也是我为什么取名为InviScript的原因. 意为INVIsible SCRIPT. 只在开发过程中存在.

不过同样高兴的是, 我选择了一个对于我个人而言, 更现实的实现, 即VEJIS. 虽然独立开发完InviScript也并非不可能, 但成本显然太过高昂…

VEJIS通过各种各样的函数, 从语法层面加强了JavaScript的功能, 提供了可以媲美甚至超过TypeScript的类/类型/模块工具, 当然因为VEJIS是运行时的脚本库, 代价就是一定的性能损耗. 这也限制了VEJIS的运用场景. 但就目前的实践经验来看, 在正确使用VEJIS的情况下, 这种影响是可以忽略不计的.

现在正在开发VEJIS 0.5, 重写了核心代码, 并提供了更多, 更具扩展性的功能. 甚至是delegate_, 虽然还没有决定是否会最终使用. 不论最终是中间语言形式的TypeScript更容易被接受, 还是运行时的VEJIS, 都一定程度反应了Web开发的趋势. 这点上, 我觉得Franky或许不会永远是对的. 😛