TONT 41973 关于注册表键值Shell Folders漫长而又感伤的故事

请注意:本页内容发布于 2268 天前,内容可能已经过时,请注意甄别。

一步错,步步错。

原文链接:https://blogs.msdn.microsoft.com/oldnewthing/20031103-00/?p=41973

When you are attempting to architect an operating system, backwards compatibility is one of the ones you just have to accept. But when new programs rely on app hacks designed for old programs, that makes you want to scream.

在对(新的)操作系统进行构架时,向下兼容性是你不得不接受并处理的事项之一。然而当某些新应用程序设计依赖为旧程序保留的补丁(hacks)时,这种做法使人真想大喊大叫一通。

Once upon a time, in what seems like a galaxy far far away (a Windows 95 beta release known as “M3”), we documented a registry key called “Shell Folders” that programs could read to obtain the locations of various special folders like the Fonts folder or the My Documents folder.

很久以前,在一个貌似遥远的星系中(某个被称作『M3』的Windows 95 beta版)(译注:此处为模仿《Star Wars》的开篇词,M3正好也是一个星团的名字),我们在文档中介绍了一个叫Shell Folders的注册表键,应用程序可据此获取某些特殊文件夹(如字体文件夹、我的文档等)的位置。

The developers who received Windows 95 M3 Beta followed the documentation and used that key.

拿到Windows 95 M3 Beta的开发者们按照文档设计,用上了这个键。

In the meantime, Windows 95 work continued, and we realized that a registry key was the wrong place to store this information. In part, because a lot of things (like the Control Panel) aren’t disk directories so they wouldn’t be expressible there. And in another part, because we had forgotten to take into account a feature of Windows NT called roaming user profiles, where your user profile can move around from place to place, so a hard-coded path in the registry is no good.

与此同时,Windows 95的开发工作也在继续,我们发现用注册表键存放这份信息不太合适。一方面,很多东西(如控制面板)并非磁盘上的目录,无法在此处合理地进行表述。另一方面,也因为我们当时忘了考虑来自Windows NT的、一个叫『漫游配置文件』的功能,用户可借此将自己的配置文件移动到其它地方,所以在注册表中硬编码这些(特殊文件夹的)路径也不合理。

So we created the function SHGetSpecialFolderLocation, and updated the documentation to instruct developers to use this new function to obtain the locations of various special folders. The documentation on the old “Shell Folders” key was removed.

所以我们又创造了一个方法SHGetSpecialFolderLocation,并对文档进行了更新,指示开发者们用这个方法来获取那些特殊文件夹的位置,有关旧的『Shell Folders』的文档内容被同步移除了。

But to ease the transition from the M3 documentation to the RTM documentation, we left the old “Shell Folders” registry key around, “temporarily”, but it was no longer the location where this information was kept. It was just a shadow of the “real” data stored elsewhere (“User Shell Folders”).

不过,为了能减缓从M3版文档到RTM版文档的过渡难度,我们还是在注册表中『临时』保留了『Shell Folders』键,不过此时它已不是相关信息存放的(一手)位置了,只是存放在别处(User Shell Folders)的某些数据的一个『影子』而已。

We shipped Windows 95 RTM with this “temporary” key, because there were still a small number of programs (let’s say four) that hadn’t finished converting to the new SHGetSpecialFolderLocation function. But the support for this registry key was severely scaled back, so it was just barely good enough for those four programs. After all, this was just a backwards compatibility hack. All new programs should be using SHGetSpecialFolderLocation.

在Windows 95 RTM版本中,我们仍旧保留了这个『临时』键,因为仍有极少数的应用程序(比方说4个)仍然没有迁移到使用SHGetSpecialFolderLocation方法上来,但对这个键的支持已经大幅度缩减了,其所能提供的好处仅限于那四个尚未迁移的新程序而已。说到底,这只是个兼容性补丁(hack)而已,所有的新程序都应该去使用SHGetSpecialFolderLocation。

In other words, the “Shell Folders” key exists solely to permit four programs written in 1994 to continue running on the RTM version of Windows 95.

换句话说,注册表键『Shell Folders』之所以存在,只是为了能让1994年编写的四个应用程序能继续在Windows 95的RTM版本上运行。

You can guess what happened next.

猜想下接下来发生了什么。

Windows 95 came out and everybody and their brother wanted to write programs for it. But reading documentation is a lot of work. So when there’s some setting you want to retrieve, and you don’t want to read documentation, what do you do? You search the registry! (Sound familiar? People still do this today.)

Windows 95上市了,所有人都想为这个新操作系统编写软件,可是读文档多累啊?所以当你想获取某个系统设置,但又不愿去读文档的话,你会怎么做呢?当然是直接搜索注册表啦!(听起来很耳熟吧?人们直到现在还这么做呢。)

So now there were hundreds, thousands of programs which didn’t call SHGetSpecialFolderLocation; they just went directly for the “Shell Folders” key. But they didn’t realize that the support for “Shell Folders” was only barely enough to keep those four original programs working.

结果就是有成百上千的应用程序根本不去调用SHGetSpecialFolderLocation,而是直接奔着『Shell Folders』那个键去了,然而他们不知道这个键只是为了支持那四个上古程序继续运行而存在的。

For example, did you know that if you never open your Fonts folder, and if no program ever calls SHGetSpecialFolderLocation(CSIDL_FONTS), then there will not be a “Fonts” entry in the “Shell Folders” key? That’s because those entries are created only if somebody asks for them. If nobody asks for them, then they aren’t created. No point setting up an app hack until it is needed.

举例来说,不知你是否知道如果你从来没有打开过『字体』文件夹,并且也没有应用程序调用过SHGetSpecialFolderLocation(CSIDL_FONTS)的话,『Shell Folders』键里就永远不会有『Fonts』这么一项?这是因为这些项只有当有人请求这些项目时,这些注册表项才会存在,如果没人请求过,那么对应的项就不会建立,毕竟补丁(hack)在不需要时就进行创建是毫无意义的。

Of course, when you’re testing your program, you don’t reformat your hard disk, install Windows 95 clean, then run your program. You just put your program on a Windows 95 machine that has been running for months and see what happens. And what happens is that, since at some point during all those months you opened your Font folder at least once, the “Fonts” entry exists and you are happy.

当然,当某开发者测试其应用时,(通常)不会格掉硬盘,全新安装一份Windows 95,然后再在上面跑测试版,而只是在一套已经跑了好久的Windows 95上运行并进行观察。然而,由于这套系统已经运行了好几个月了,而这期间『字体』文件夹又至少被打开了一次,『Fonts』这个注册表项就存在了,于是皆大欢喜。

And then back in our application compatibility labs, your program gets a “Fail” grade because our lab reformats the computer before installing each application to make sure there is nothing left over from the previous program before installing the next one.

然后这份应用来到了微软的兼容性测试实验室,并被评级为『不合格』,因为我们的实验室会在安装每一个新的实验对象前,对系统进行格盘全新安装,以确保不会残留有上一个实验对象留下的东西。

And then the core development team gets called in to figure out why this program is getting a “Fail” grade, and we find out that in fact this program, when faced with a freshly-formatted machine, never worked in the first place.

接着我们的核心开发组人员就会被叫来,评估为什么这个程序得了个『不及格』,最后发现,实际上当这个程序被安装到全新安装的机器上时,从一开始就不会正常运行。

Philosophical question: If a program never worked in the first place, is it still a bug that it doesn’t work today?

这里有个哲学问题:如果某个程序一开始就不能正常运行,那直到今天仍然不能运行算不算一个bug呢?

Now there are those of you who are licking your lips and saying, “Wow, there’s this ‘User Shell Folders’ key that’s even cooler than the ‘Shell Folders’ key, let me go check it out.” I implore you to exercise restraint and not rely on this new key. Just use the function SHGetFolderPath, which returns the path to whatever folder you want. Let the “User Shell Folders” key rest in peace. Because in Longhorn, we’re doing even more stuff with user profiles and I would personally be very upset if we had to abandon the “User Shell Folders” key as “lost to backwards compatiblity” and set up shop in a new “Real User Shell Folders” key.

可能这会有人会舔舔嘴唇(译注:?)说道,『哎呀,这儿还有个叫User Shell Folders的键,比那个Shell Folders还要帅,研究一下。』算我求你了,管管自己别这么做,也别依赖这个新的注册表键,就用SHGetFolderPath来获取你所要的系统文件夹的位置不行吗,让User Shell Folders安静一下吧。因为在Longhorn中,我们对用户配置文件做了更多的开发,而如果以『丧失向下兼容性』为代价抛弃User Shell Folders这个键,并把所有的东西都搬进一个新的『Real User Shell Folders』键里,我个人会非常狂躁的。

I strongly suspect that of those four original programs for which the “Shell Folders” key was originally created, not a single one is still in existence today.

如今的我,非常坚定地怀疑,当初为了它们而保留了Shell Folders这个注册表键的那四个程序,已经没有一个还活在世上了。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

 剩余字数 ( Characters available )

Your comment will be available after auditing.
您的评论将在通过审核后显示。

Please DO NOT add any links in your comment, otherwise it would be identified as SPAM automatically and never be audited.
请不要在评论中插入任何链接,否则将被自动归类为垃圾评论,且永远不会被提交给博主进行复审。

*