Windows 95 插件即插即用背后的“版权大战”

Windows 95 的即插即用功能的实现并非一帆风顺。为了让旧硬件兼容新功能,工程师们费尽心思。一个有趣的案例是,一些厂商为了免费获得LitWare文字处理软件的完整版,会在BIOS中添加“Not Copyright Fabrikam Computer”字符串,从而欺骗软件的授权检测机制,绕过试用版限制。这展现了早期PC兼容性挑战以及厂商之间为争取软件授权而采取的策略。
阅读更多
Windows 95 的即插即用功能的实现并非一帆风顺。为了让旧硬件兼容新功能,工程师们费尽心思。一个有趣的案例是,一些厂商为了免费获得LitWare文字处理软件的完整版,会在BIOS中添加“Not Copyright Fabrikam Computer”字符串,从而欺骗软件的授权检测机制,绕过试用版限制。这展现了早期PC兼容性挑战以及厂商之间为争取软件授权而采取的策略。
阅读更多
十个月前,我从Contoso公司删除了我的账户,并收到了账户信息已永久且不可逆转删除的确认邮件。然而,昨天我却收到了Contoso公司更新隐私政策的邮件,这意味着他们所谓的“永久删除”根本就是谎言,因为他们仍然保留着我的邮箱地址。这引发了人们对数据隐私和公司承诺可信度的质疑。
阅读更多
本文探讨了一个C++模板继承中关于拷贝构造函数的令人费解的问题。`Derived`类继承自`Base`类,`Base`类的拷贝构造函数被删除。然而,`Derived`类定义了自己的拷贝构造函数,即使该构造函数尝试拷贝`Base`类的不可拷贝对象,`std::is_copy_constructible`仍然返回true。这是因为编译器只检查是否存在非删除的拷贝构造函数,而不检查其可否实例化。作者进一步讨论了显式定义拷贝构造函数和隐式定义拷贝构造函数的区别,以及将拷贝构造函数定义移出类的影响。
阅读更多
.NET 10 Preview 4 推出了一个令人兴奋的新特性:可以直接使用 `dotnet run app.cs` 运行 C# 文件,无需创建项目文件或搭建整个应用程序。这使得 C# 的入门变得比以往任何时候都更容易,非常适合学习、原型设计或编写小型脚本。该特性支持使用 `#:package`、`#:sdk` 和 `#:property` 等指令直接在 .cs 文件中引用 NuGet 包、指定 SDK 和设置 MSBuild 属性,并兼容 MSBuild 概念。即使脚本发展成为完整的应用程序,也可以无缝转换为基于项目的应用程序。此功能简化了 C# 开发体验,降低了学习和使用的门槛,为 CLI 工具、自动化脚本和工具提供了便利。
阅读更多
微软为64位Windows系统带来一款全新的轻量级命令行文本编辑器——Edit。Edit开源且体积小巧(小于250KB),支持鼠标模式、多文件打开、查找替换、单词换行等功能,并采用无模式设计,避免了类似Vim的学习曲线难题。它将在未来几个月内通过Windows Insider Program进行预览,并最终集成到Windows 11中。
阅读更多
一位网友分享了他对一套MS-DOS图标集的独特见解,认为其比Windows程序管理器自带的图标集更有实用价值。文中列举了多个例子,例如微软Basic编译器、Microsoft Project、Close-Up 4.0等程序的图标,并解释了这些图标在当时是如何被使用的,以及一些图标设计上的不足之处,例如过时的MS-DOS标志或不合适的叠加层。这篇文章引发了对早期软件界面设计和怀旧情怀的讨论。
阅读更多
作者多年来一直使用Windows 95默认的纯色壁纸。然而,他发现使用纯色壁纸的Windows 7系统登录时,欢迎界面会停留30秒。这并非登录时间变长,而是由于系统在等待壁纸加载完成的信号,而纯色壁纸由于缺少位图信息,导致该信号无法发出,从而触发了30秒的超时机制。类似地,“隐藏桌面图标”的组策略也存在类似问题,其代码逻辑错误导致图标就绪信号无法发送。最终,微软在Windows 7发布后几个月解决了这个问题。作者也因此分享了他偏爱默认设置的原因:这方便了bug报告和修复。
阅读更多
一个客户遇到了一个长期存在的低频挂起问题:UI线程调用内核后卡住。内核转储无法显示用户模式堆栈,因为堆栈已被换出。调查发现,一个看门狗线程会周期性地挂起UI线程以获取堆栈跟踪,但这次却卡住了5个多小时。原因是:看门狗线程在获取UI线程堆栈跟踪时,需要获取函数表锁,而UI线程正处于挂起状态,持有该锁。这导致了死锁。文章强调了不要在自己的进程中挂起线程,因为它可能导致因被挂起线程持有资源而造成死锁。如果需要挂起线程并获取堆栈跟踪,应该从另一个进程进行操作,避免死锁。
阅读更多
早期的USB鼠标经常附带一个USB转PS/2的绿色适配器。这并非一个智能转换器,它只是简单的物理连接,没有任何电路。真正的转换工作是由鼠标本身完成的,它能检测并根据收到的信号(USB或PS/2)调整自身行为,就像转换不同国家电源插头的适配器一样,智能在设备本身。所以,如果你找到这样的适配器,它只是一个物理连接件,真正的转换发生在双总线鼠标中。
阅读更多
一位同事在每周的调试例会上遇到一个棘手的并发问题:关键代码段未能阻止两个线程同时进入,导致TraceLoggingRegister重复注册失败。深入调试发现,问题源于`RtlRunOnceExecuteOnce`的初始化函数`InitializeCriticalSectionOnce`错误地返回了`STATUS_SUCCESS` (0),导致`RtlRunOnceExecuteOnce`认为初始化失败,每次调用都重新初始化临界区,从而引发并发问题。最终解决方案是将返回值改为`TRUE`,或者更简洁地用`SRWLOCK`代替`CRITICAL_SECTION`。这个案例警示了细微的返回值错误可能导致严重后果,并强调了选择合适的同步原语的重要性。
阅读更多
TypeScript团队宣布将TypeScript编译器和工具移植到原生代码,以显著提升性能。该原生实现预计将使编辑器启动速度大幅加快,构建时间缩短10倍,并大幅减少内存使用。初步测试结果显示,对多个大型项目(如VS Code、Playwright)的编译速度提升了10倍以上。未来,原生TypeScript(计划命名为TypeScript 7)将支持更高级的重构和更深入的代码分析,并为下一代AI开发工具奠定基础。TypeScript 6(基于JS)将继续维护,以确保平滑过渡。
阅读更多
C++/WinRT 的一个 pull request 修复了 `winrt::impl::promise_base::set_completed` 中由于参数相关查找(ADL)导致的 `invoke` 函数调用歧义问题。由于 C++20 正式支持协程,导致查找范围扩大,意外找到了 `std::invoke`,而非预期的 `winrt::impl::invoke`。文章详细解释了 ADL 机制,并提供了针对旧版 C++/WinRT 的补丁方案:在 `winrt::Windows::Foundation` 命名空间中声明一个更匹配的 `invoke` 函数,从而引导编译器选择正确的函数。此补丁还包含一个静态断言,确保在升级 C++/WinRT 后自动失效。
阅读更多
本文探讨了在C++枚举类型中使用“其他”值(例如WidgetFlavor::Other)的潜在问题。当添加新的枚举值时,如何处理这些新值,以及如何保证与旧版本代码的兼容性,是一个难题。作者建议避免使用“其他”值,而应将枚举声明为开放式,让程序自行处理未识别的值,从而更好地解决版本兼容性问题。这避免了添加新枚举值时可能造成的代码混乱,并确保新旧代码能平滑过渡。
阅读更多
微软大幅提升了 MSVC Address Sanitizer (ASan) 的质量。他们将 ASan 的主要部分上游到 LLVM,从而能够更快地整合 LLVM 社区的改进。此外,他们还将 ASan 集成到 MSVC 代码库中,包括编译器、链接器和工具,从而在持续集成中检测内存安全问题。Visual Studio 2022 版本 17.13 中修复了许多问题,包括减少误报、改进错误报告和处理多进程场景。
阅读更多
本文讲述了Windows 95安装程序的幕后故事。为了创建一个简单的安装程序,开发团队不得不在MS-DOS环境下从零开始构建一个微型操作系统,包含图形库、窗口管理器、多语言支持等功能,甚至还需要考虑兼容Windows 3.1环境。最终,他们意识到与其重新造轮子,不如直接使用现成的Windows 3.1运行时环境,避免了巨大的开发工作量。这突显了软件工程中“复用”的重要性,也揭示了Windows 95安装程序的复杂性远超人们想象。
阅读更多
Windows 95 的“现在可以安全关机”提示,你是否还记得?文章讲述了一个发生在飞机上的小故事:作者的邻座乘客因为不了解旧款电脑的关机机制,在看到“Windows 已关闭”的屏幕后反复点击“重新启动”,最终在作者的指点下才明白需要手动按下电源键关机。这个故事展现了早期电脑缺乏电源管理功能的时代背景,也解释了 Windows 95 加入该提示的原因:它温柔地提醒用户,可以安全地按下电源键了。
阅读更多
在一次 USB 规范会议上,一家公司展示了他们的 USB 软盘驱动器,令人惊讶的是,他们分别为 PC 和 Mac 提供了两个版本。委员会成员感到困惑,因为规范确保同一驱动器可在两种系统上工作。结果,公司代表解释说,两个版本的驱动器电子元件完全相同,唯一的区别在于 Mac 版本采用半透明蓝色塑料外壳,价格也更高。这反映了当时 iMac 半透明塑料的流行趋势,也凸显了部分厂商利用设计差异进行溢价的策略。
阅读更多
一个开发人员讲述了导弹软件中巧妙运用“零垃圾回收”的案例。由于导弹飞行时间有限,且硬件内存充足,即使程序存在内存泄漏,也不会造成问题。工程师们计算了程序在飞行过程中可能产生的内存泄漏量,并为其增加了双倍的内存空间,以确保程序在导弹完成任务前不会崩溃。这种方法充分利用了程序运行时间的限制,巧妙地解决了内存泄漏问题,堪称“终极垃圾回收”。
阅读更多
Go 1.24 对其加密库进行了大规模重构,以实现 FIPS 140-3 标准合规性。这标志着 Go 标准库的一个重大飞跃,其纯 Go 实现的 FIPS 140-3 认证加密模块不再依赖 cgo 或系统调用。微软 Go 1.24 也做了相应更新,支持 macOS 预览版和增强 Azure Linux 支持,但其加密策略与官方 Go 版本不同,继续使用系统库。新的环境变量 GODEBUG=fips140=on 和 GOFIPS140=latest 控制 FIPS 模式。在 FIPS 兼容系统(如 Azure Linux 或 Windows)上,运行时会自动启用 FIPS 模式。
阅读更多
经典的Windows 3D Pipes屏保,以其迷人的管道动画而闻名,却隐藏着一个鲜为人知的秘密:一个极低概率出现的茶壶。这个茶壶致敬了计算机图形学中的Utah茶壶,但其出现概率之低,导致用户抱怨效率低下。文章还揭露了该屏保在旧版Windows系统中,因软件渲染导致服务器CPU占用过高的问题,建议在服务器上使用黑色屏幕屏保。
阅读更多
一位开发者在C++项目中添加XAML支持时,仅仅包含winrt/Windows.UI.Xaml.h头文件就引发了一系列编译错误。错误源于一个看似正常的函数声明:`template struct consume_Windows_UI_Xaml_IExceptionRoutedEventArgs { [[nodiscard]] auto ErrorMessage() const; };` 实际上,开发者项目中存在一个名为ErrorMessage的宏,与函数名冲突。该宏用于创建ErrorMessageString对象,并返回一个指向错误消息字符串的指针。宏的无边界性导致编译器误将函数声明解释为宏调用,从而产生“参数不足”等错误。解决方法是:在包含头文件之前,使用#pragma undef禁用宏,或直接移除宏,使用内联函数替代。
阅读更多
Windows 95安装程序之所以使用MS-DOS、Windows 3.1和Windows 95三个操作系统,是为了兼顾从这三个平台进行升级的用户。为了避免编写三个独立的安装程序,Windows 95采用了一种链式安装方式。首先,如果从MS-DOS升级,会安装一个精简的Windows 3.1版本。然后,一个16位Windows程序负责收集用户信息、检测硬件、复制文件和迁移设置。最后,在Windows 95中运行的32位程序完成最后的安装步骤,例如安装打印机。这种方式使代码只需编写一次,即可用于所有升级场景。
阅读更多
本文探讨了Unicode中一种特殊情况:标题大小写(Title case)。某些Unicode字符,例如dz (U+01F1 LATIN SMALL LETTER DZ),表示两个图形符号的组合,但占用单个代码点。这些字符主要出现在匈牙利语等语言中,被视为字母表中的单个字母。Unicode包含四个这样的双字母组合,它们具有大写、标题大小写和小写三种形式。文章指出,dz双字母组合的存在源于塞尔维亚-克罗地亚语中拉丁字母和西里尔字母的转换需求。文章还讨论了这种特殊字符在文本搜索中可能导致的问题,例如搜索"mad"不会匹配"madzag",因为"dz"被视为单个字母。
阅读更多
文章指出,逐个字符地将字符串转换为大写或小写是一种流行但错误的方法。因为它没有考虑到字符集、上下文以及字符长度变化等因素。例如,使用`std::tolower`或`std::toupper`无法正确处理UTF-8和UTF-16编码的字符串,并且在某些语言中,大小写转换还会改变字符串长度。文章建议使用`LCMapStringEx`或ICU库中的`u_strToUpper`和`u_strToLower`等函数来进行大小写转换。
阅读更多
std::monostate 是 C++17 中引入的一种类型,它没有任何成员,所有实例都被认为是相等的,其作用是一个占位符类型,用于表示不需要任何值的状态。例如,在 std::variant 中,可以使用 std::monostate 作为初始类型,使其能够在空状态下进行默认构造。
阅读更多
文章讲述了一个程序员在实习期间,在Windows 3.1代码中植入了一个恶作剧代码,将鼠标指针变成了中指,结果该版本被发布,引发了轩然大波。尽管这名程序员已经结束了实习,但在正式入职前,公司迫于压力“解雇”了他以平息风波。
阅读更多
微软宣布将从2024年8月15日起,逐步停用Microsoft Teams中的Office 365连接器功能,并推荐用户使用Power Automate workflows作为替代方案。Power Automate workflows不仅提供更丰富的连接器目录,还能确保集成架构的灵活性和安全性,满足不断增长的业务需求。文章还提供了从Office 365连接器迁移到Power Automate workflows的详细步骤。
阅读更多
这篇文章探讨了在Windows系统中,使用Alt+数字键输入字符的历史和原因。文章解释说,在IBM PC BIOS中,Alt+数字键的输入方式是将数字作为十进制字节值处理,并从显卡的字符生成器中查找对应的字符。在Windows中,为了与MS-DOS兼容,使用Alt+数字键输入时,数字仍然会在OEM字符集中查找。文章还解释了为什么Alt+9731有时会显示心形,有时会显示雪人,这取决于使用的控件类型。
阅读更多
本文是微软工程博客关于Dev Drive和写时复制(CoW)技术的后续文章。文章首先展示了CoW技术在大型代码库中提升编译速度的测试结果,特别是在C#项目中效果显著。然后,文章讲解了如何判断一个文件是否是CoW链接,以及如何在使用Dev Drive时配合ProcMon和Xperf进行性能分析。最后,文章还提供了解决CoW引用泄漏问题的步骤。
阅读更多
文章介绍了一种高效比较压缩位域的方法。传统的按位解压方法效率低下,而预留填充位的方法又浪费空间。文章介绍了一种利用“借位向量”的技巧,通过计算减法的借位向量,判断是否存在字段值小于的情况,从而实现高效比较。
阅读更多