TypeScript on Electron 解决 Renderer 没有 exports 的问题

Electron 的 Renderer process 虽然和 main process 是不同的进程,但依然可以使用 node 的环境,比如 require(‘fs’) 之类. 但如果一个 js 脚本是在浏览器环境中用 <script> 标签加载的话,exports 变量是缺的,会报 exports is not defined.

而解决方法是不要使用 <script src=”./script.js”></script> 而是 <script>require(‘script’);</script>. 这样所有的脚本就是以 module 的方式加载而不是页面脚本了. 以 module 方式加载的脚本是有 exports 变量的.

继续阅读 »

使用 VSCode 运行 Task 并自动 Attach Debugger

本文将讲述如何在 VSCode 中使用 Attach 模式 Debug 的时候,也能像 Launch 模式一样一键启动 Debuggee. 具体原理是使用 preLaunchTask 并将此 Task 的 isBackground 属性设置为 true.

VS Code Debug Protocol 描述了两种不同的 Debug 方式:Launch 以及 Attach. 他们分别对应了 VSCode 负责启动程序并 Debug,以及 VSCode 去 Debug 一个正在运行的程序,包括非本地的程序.

其中,Launch 模式的潜在含义是,VSCode 将负责管理 Debuggee 的生命周期,也就是说 VSCode 负责启动及停止,而这些操作对于用户而言就是按一下按钮. 反观 Attach 则是另一种设计:用户必须自行启动 Debuggee,可以在本地可以在远程,只要 Debugger 能够与之通信,而 VSCode 只负责将 Debugger 与 Debuggee 对接.

在本地开发本地运行本地调试的情况下,Launch 无疑是最好的选择,因为一旦配置完毕,今后 Debug 只需要一键启动及一键停止. 这种开发环境十分的理想化,尽管可以满足大多数需求,但当环境变得复杂时,Attach 模式将是无法避免的. 例如执行代码的机器一定是在远程,这常见于跨平台开发,包括在 Windows 上使用 WSL 做 Linux 开发,以及使用 QEMU + GDB 做内核开发. 尽管微软在近期对一些官方插件就 WSL 进行了优化,即可以使用 Launch 模式在 WSL 中运行程序,但第三方插件仍然不可避免地需要使用 Attach.

继续阅读 »

在 WSL 中使用 ssh-agent

在阅读前请注意,ssh-add 在没有 keychain 的情况下只能临时保存 SSH key. 也就是说重启 ssh-agent 后需要重新 ssh-add. 若要永久添加某个 SSH key,最快捷的方法是在 ~/.ssh/config 中添加 IdentityFile. 但如果要使用 SSH agent forwarding,就需要 ssh-agent 了.

在 WSL 中自动启用 ssh-agent 并不是那么直接,因为 WSL 的入口 bash.exe 并不能继承来自父进程关于 ssh-agent 的环境变量,毕竟父进程是个 Windows 进程. 此外另一点特殊的地方在于,当所有 bash.exe 进程结束的时候,所有的 WSL 进程会被杀掉,包括 ssh-agent.

ssh-agent 的启动比较特殊. 手动启动的方式是:

这是因为 ssh-agent 默认执行两件事:1. 后台运行 ssh-agent;2. 输出一段 shell script 以供执行. 这段 shell script 中包含着与这次启动的 ssh-agent 通信所需的环境变量.

一般情况下,例如在 Linux 桌面环境里,在桌面环境启动前 ssh-agent 就被启动并且环境变量也被设置了. 之后启动的桌面环境,以及桌面环境启动的 Terminal 都会自动继承这个环境变量.

继续阅读 »

用六面不均匀的骰子模拟一只六面均匀的骰子

最近被问到了这么一个问题,蛮有意思的. 这里可以做一个额外的限定:在有限的步骤内精确地将发生的事件分割成六个概率为 1/6 的部分,而不是随着操作次数的次数增多趋近 1/6.

经过了一段时间的探索之后,我发现想要通过重复掷固定次数的骰子来达成这一目标,在知道六面各自的概率后,是不存在一个策略可以把所有发生的事件精确地分割成六份的.

我将借助超越数,使用反证法来证明这一点.

为了证明这一点,首先可以做一些化简. 六面的骰子过于复杂,可以先尝试减少到两面,也就是把骰子简化成硬币. 假设这样的策略是存在的,也就是给定一个六面概率不一的骰子及其各面概率后,就可以得到一个正整数 n,然后掷这个骰子 n 次,根据每次掷的结果将结果分为等概率的六份. 然后假设存在一种只有两面的各面概率不一的骰子.

首先,这个两面骰子可以做到六面骰子的效果. 方法是掷三次两面骰子,可以得到八种不同的结果,将这八种结果分为六份(不能有任何一份是空的),就可以得到六个概率不一的事件集. 而根据刚才的假设,知道了六种结果的概率后,把它当作一个六面的骰子,重复 n 次掷骰子的操作,然后就可以得到均匀概率的六组结果. 最后,将这六种结果的其中三种分为一组,另三组分为一组,这样就得到了均匀概率的两组结果. 也就是说,当六面骰子的策略存在的时候,两面骰子的策略也同样存在.

继续阅读 »

在 WSL 中使用 pulseaudio 播放声音

虽说微软最初发布 WSL 的时候就明确表示这是一个只针对开发者的平台,而现在的战略也只是更进一步支持服务器级别的应用,并没有支持桌面应用的计划(可是 CUDA 和 OpenCl 你总得支持吧),但我在很愉快地用它开发之余,也在很愉快地看热闹不嫌事大地企图让各种 GUI 应用跑起来. 得益于类 unix 系统上显示与音频的网络化设计,可以在 Linux 完全没有相关硬件资源的情况下通过网络方式用 Windows 上的服务器显示与播放,再加上 WSL 和 Win32 本身就是同一内核上的两个子系统,这样做相当于就是在原生 Linux 上正常使用声音与显示,只是没有高效的 unix socket 罢了.

关于 WSL 上跑 GUI 的相关文章已经相当多了,然而播放声音的却没有一篇完整的教程. 这里将介绍如何使用 pulseaudio 来让 WSL 播放声音.

继续阅读 »

Windows 10 + OS X 硬盘升级无损迁移记实

注:本篇是对我自己做系统迁移的整理并不是一篇教程,仅供参考

注2:仅可应用于 EFI 安装的 Windows,也就是说 Windows 7 以下绝对不是

注3:数据无价 谨慎操作 —— Disk Genius

前情提要

出于一些原因我的 mid 2014 11″ MacBook Air 用的是 128G 的硬盘,这显然不够我装 Windows + macOS 双系统并且各种 IDE 和 runtime 全部装上的. 光是 Visual Studio 和 XCode 就要占掉 30G – 40G 的空间,而 Windows 又是个吃硬盘的怪兽,随着补丁的增加留给 macOS 的空间越来越小,最终变成了 70G Windows + 40G macOS 的划分. 就这么凑合用了两年,最终省吃俭用抠下来的空间都不够 Windows 装个补丁以及 XCode 跑过升级了. 想想这台电脑除去硬盘用个五年没问题,就这么换新未免有些 overkill.

因此就有了硬盘升级的需求. 淘宝上现在有很多原厂的 mac 硬盘可以更换(甚至主板都能换,也就是连带 CPU 和内存),有些店家甚至提供了店内帮你更换的服务并回收完好的老硬盘帮你节省一点成本,免去了自行操作的风险和麻烦. 所以剩下的工作就只有系统迁移了.

基本思路

分区示意

硬盘里有几个不能动也不用动的分区,比如引导用的 EFI 分区、Windows 需要的 MSR 预留分区、macOS 的恢复分区,装了 Linux 的话还可能会有 grub 和 swap 分区. 这些分区只需要原样复制过去就行. 剩下的就是装着系统的分区了,硬盘升级后最主要的用途就是扩大系统分区的容量,所以它们都需要扩容. 每个操作系统和文件系统的扩展工具都不同.

扩容

所以 Macbook 做硬盘升级 + 系统迁移的基本思路就是:先在移动硬盘里做老硬盘的全盘备份,然后升级硬盘,再把不用动的分区原样复制(按扇区复制)到相应的位置,预留下需要扩容的分区空间,再把需要扩容的分区复制到相应的位置并扩容.

继续阅读 »

Lambert W function 数值计算

由于一些很蠢的原因,我写了一份完全用不着的用于计算 Lambert W function 的 C# 代码. 具体原理是很粗暴的牛顿法求解,但有几个特别处理的地方:

首先是估算. W0比较好处理,其实随便给个初始值就好,我这里选择了偏移后的 ex. 而 W-1 则比较特殊,首先在 x < -2 的部分变成了 concave 的,而且越往左斜率越小,所以一律从 x = -2 开始尝试;而在 -2 < x < -1 的区间内其实也是随便给个初始值就好,我这里选择了偏移后的 cos 函数.

其次是精度处理. 通过 log2x 做差可以求出二进制下的有效数位,然而当 y 值较大的时候其实并不能把完整的 52 位双精度浮点数的小数部分求完整,大概只能求到 47 位左右,所以这里我保守选择了 42 位有效数字.

继续阅读 »

CanvasRenderingContext2d bug 2 则,附解决方案

前言:这篇文章本来是上上次在 Autodesk 实习结束的时候 (2015.12) 就要发的,后来存在草稿箱给忘了,现在这两个 bug 并不知道还存不存在,本来是有计划写详细的代码示例的也搁置了.

第一个 bug 仅影响 Windows 平台的 Firefox.

当在 clip 过的 context 中绘制阴影时,如果在本次渲染周期前没有任何 fill 操作,clip 会失效. 后果是 clip 外的内容会被覆盖.

解决方案是在所有渲染操作前绘制一个透明的像素.

第二个 bug 有关于 IE 的 CORS.

IE 是部分支持 CORS 的,比如如果请求头设置正确的话图像是可以在 <img> 中正确加载并显示的,也可以通过 Image 类加载并绘制到 canvas 中. 然而,通过后者绘制的 canvas 将不能使用 toDataUrl (会报 SecurityError 异常).

解决方案是先使用 XHR 载入图像数据,然后将 ObjectUrl 赋值给 Image.src. 感谢微软,至少 XHR 的 CORS 还是能用的. (此处应有一颗药丸)

.NET Core 调用 native library 的 project.json 写法

太长不看版:

一点废话:最近在用 ASP.NET Core 练手,想把去年 CS246 (C++) 的期末大作业做个 web interface. 当时选做了国际象棋,整个 C++ 代码从设计到完成,还附带一个不带 WebSocket 的用 ASP.NET Core beta5 (当时还叫 ASP.NET 5) 写的简易 web interface 作为附加分,一共也就用了 50 小时 (虽然忘记做王车移位时不能被将的判断了) 其中还有至少 4 小时花在了将 还处在 beta 的 ASP.NET Core 部署在 Amazon Linux 上. 而现在,我花在这个 web interface 上的时间可能都超过 100 小时了,看来核心业务逻辑果然是只占有非常少的比例啊…

这次要说的是,如果 C# 中要调用 native library,也就是要用 DllImport,那在 project.json 中应该如何导出这个 dll. 撰写此文的时候是 2016/09/10 版本是 .NET Core 1.0. (按照微软的尿性谁知道下个版本这么写还对不对)

继续阅读 »

Amazon Linux 编译安装 mono 并后台运行 ASP.NET5 应用(supervisor)

目前 ASP.NET5 环境仅对 Ubuntu 支持得比较好,而使用 yum 的几个 Linux 则需要花一些时间去安装了(理论上讲 mono 提供了 yum 的包,但实际安装的时候报缺少 libpng15.so,并没有找到任何方法修复). OS X 和 Windows 当然是一路绿灯并没有什么问题. 不巧的是我的 Amazon EC2 跑的是 Amazon Linux,折腾了一个礼拜才最终搞定.

首先当然是安装 mono. 安装过程可以参考 mono 官方的教程. (需要先安装 git 和 make)

注意:编译安装 mono 需要花费较长的时间.

继续阅读 »