你可能观察到了这样一种现象:如果你将一个USB设备连接到电脑,Windows会自动识别和配置这台设备。然后,当你将它断开连接,然后重新连接到电脑上的另一个USB口,则Windows好像失忆了一般,它会认为这台设备是一台全新的设备并重新配置,丝毫没有察觉到,这台设备之前已经完整的配置过了。这是为什么呢?

USB设备开发团队对此的解释是,如果一台USB设备没有可用的序列号,则就会发生如上的情况。

需要注意的是,序列号对于USB设备来说,是可选的属性。如果一台USB设备有序列号,则Windows会识别该设备,而不管设备是接入到哪个USB口。如果它没有序列号,则Windows会认为接到不同的USB口上的设备都是一台全新设备。

(我记得,一个USB设备的主流厂商没有很理解序列号的工作原理。他们虽然为他们生产的USB设备都配置了序列号,这很好,但是这些序列号都是同一个。这就尴尬了,当同时在一台电脑上的不同USB口上接上他们的设备时,奇怪的事情就会发生。)

有人会问了,如果 Windows 缺少序列号并显示在不同的端口上,为什么它会将其视为不同的设备呢? 为什么它不能只是说,“哦,你在那里,在另一个口的那边。”

因为这样设计的话,当你接2台相同类型的设备时,会产生随机行为。
根据即插即用枚举设备的顺序,这两组设备上的设置在每次启动时似乎是随机分配的。 今天设置以一种方式匹配,但明天当设备以另一种顺序枚举时,设置被交换。(如果你以不同的顺序插入设备,你就会得到类似的,令人困惑的行为。)

换句话说:事情很糟糕,因为
(1) 事情已经很糟糕了 – 如果设备有正确的序列号,这不会成为问题。
(2) 一旦你处于这种糟糕的状态,替代方案就更糟糕了。USB堆栈只是试图在糟糕的情况下做到最好,而不会使情况变得更糟。

总结

为了成为Windows世界的良好公民,正确的设计方案是:为你的每一台USB设备都分配独一无二的序列号。
随机化是一个对机器来说十分友好的东西,虽然人类可能不太喜欢这类东西,毕竟,一个随机字符串很难记忆。
在拓扑梅尔智慧办公平台(Topomel Box)的开发过程中,我大量的使用了随机字符串,这样的设计有两个好处,其一是实现了语言的中立性,二是进一步提升了二进制代码的安全性。