| |
首页 淘股吧 股票涨跌实时统计 涨停板选股 股票入门 股票书籍 股票问答 分时图选股 跌停板选股 K线图选股 成交量选股 [平安银行] |
股市论谈 均线选股 趋势线选股 筹码理论 波浪理论 缠论 MACD指标 KDJ指标 BOLL指标 RSI指标 炒股基础知识 炒股故事 |
商业财经 科技知识 汽车百科 工程技术 自然科学 家居生活 设计艺术 财经视频 游戏-- |
天天财汇 -> 科技知识 -> 为什么 Windows 的兼容性这么强大,到底用了什么技术? -> 正文阅读 |
|
[科技知识]为什么 Windows 的兼容性这么强大,到底用了什么技术? |
[收藏本文] 【下载本文】 |
Win10 连98年出的VB6都能运行,黑科技啊。。。 [图片] |
感觉主要还是在于: 已有的 API 哪怕不推荐了也不会删除,一直留着一直能用,要修改 API 则另起一个新的,于是你会看见同一个叫做 Xxx 的 API 可能会出现 XxxA、XxxW、Xxx2、XxxEx 等等。已经过时的技术哪怕不推荐了也不会删除,也一直留着一直能用。你敢想象 RDP(远程桌面)的组件是一个 ActiveX 组件,并且至今仍在被大量的应用甚至是新应用使用(虚拟机软件的监视器、WSLg 的窗口以及各种远程桌面客户端等等)。然而 ActiveX 本身早已经是不推荐的技术。同理还有上世纪的 OLE 技术造就的 VB6,至今仍然躺在 Office 2022 里。各种依赖(vcrt、.NET、DirectX 等等)都采用 side by side 方式部署,多个版本共同存在,不会出现类似升级个 glibc 一堆软件挂了的问题。大量使用 COM 来暴露接口,这个东西有着极其离谱的兼容性,能够做到扩展接口的同时不破坏掉兼容性。旧程序无需重新编译就能直接使用新的 COM 接口的实现,只要新的 COM 接口是从旧的接口上继承过去的。此外 COM 接口有个特性:哪怕是修改原来的接口,只要新增的方法放在最后面,就不会破坏掉已经用了这个接口的应用的兼容性。Windows 整个系统里各组件交互可以说都是在 COM 上搭建起来的,做到了完全解耦,也正是因为有 COM,Windows 才能做到如此的兼容性。而 Linux 则是建立在字符串上的,一旦字符串追加了内容或者更改了格式就会造成预料之外的错误,而 COM 则不存在这个问题。于是你可以看到老的 Win32 应用技术并没有升级却能用上新的 XAML 现代组件、早已经停更的 IE6 却被人接上了 chromium 的 v8 引擎等等奇观,不需要套壳包装,而是新老组件在同一个 app 上和平共处还能相互调用。并且 COM 接口调用的效率还非常高,跨进程调用开销约 0.01 毫秒,进程内调用开销不到 0.00001 毫秒(10 纳秒),在 2022 年的今天仍然没有更好的替代品。对于部分行为的更改(尤其是安全方面),例如以前非法访问内存、二次释放内存不会报错终止进程,而后来修复了这个行为后导致一些有 bug 但是以前碰巧没问题的应用在新版本 Windows 上跑不了了,这个时候 Windows 会在系统里添加特殊规则使得那些程序能够非法访问内存、二次释放内存的时候不崩溃。如果涉及到架构变化的话,会在系统层面实现对原来架构的转换层。例如 x86 32 位系统带了 16 位转换层,使得系统能运行以前的 16 位 DOS 程序;而 64 位系统自带了 WoW64,使得所有 32 位应用都能正常运行;而 Arm64 的 Windows 则带了 x86 的 32 位和 64 位两套转换层,兼容以前所有的程序。如果某个设计或者 API 的实现有 bug 但却被很多应用依赖了这个 bug 的行为,则会保留着这个 bug 不进行修复。哪怕是 API 的名字错了个字,对强迫症很不友好,但就是会一直留着不修正,例如 GetBaseIndicies,Indices 多打了个 i,但是不好意思,不能修,他们自己再难受都不能修。 |
大家都说了,一坨伟大的屎山。 我记得苹果IOS就有一个API删除了,导致微信崩溃无法运行,后来又把API接口还原了,还特地加了注释:不知道微信为什么要调用这个API。。。 |
二十年前读过的一本书,讲COM组件技术的,受益匪浅 |
![]() |
这东西是windows系统的基石,win32 api是COM的壳子,了解这个就知道为啥windows兼容性这么强了 |
Windows 有个目录叫 system32,这里面好多文件我估计微软自己都说不清干嘛的,也不敢删除 |
还不是惯着用户呗 时不时还给Xp打个补丁 跑不了的旧程序还可以用兼容模式试试 当然苹果是最牛逼的,换手机不够勤快就会贴心地给你降个频.... |
黑科技主要都在 %windir%\apppatch下面。*.sdb里面是很多规则(xml定义然后转成二进制方便查询),进程启动时会查询,有匹配则使用。比如有针对 Visual Basic 6.0的,内容可能是某些配置,像是禁用某些新的安全特性,还可能是某些API行为变化导致不兼容,所以detour到兼容的实现。兼容的实现大多放在前面目录下的DLL里。 当然这些规则都是一条一条手工加的,一个规则对应一个或者多个bug。 最新的Windows 10 on ARM的兼容性更有意思,除了应用x86已有的,还有一些神奇的规则,比如不让旧的x86程序检测到自己运行在64位系统上。 |
做兼容性强的系统,不需要任何秘术。只需要你: 更新系统的时候不故意破坏兼容性。用户不兼容你的时候帮用户解决。 只不过,这两条没有钱和人力,没有很多很多的钱和人力,你是做不到的。 |
按照Windows这逆天兼容性 我觉得如果微软能活到2124年 说不定那个时候能人还能在Windows上玩1990年代的PC游戏 |
Android,IOS,MAC,甚至很多新的LinuX发行版,都已经取消了对32位软件的兼容性,只保留64位兼容。 只有微软,都win11了居然还没砍掉32位软件支持! |
我说一件同学们很少提到的事,Windows 有个兼容性逆天,统一的 LibC(现在是 UCRT)。恐怖如斯,常年在 Linux 下搞开发的同学都明白这意味着什么。 |
就是有一个原始版函数叫FUNC 但是过了段时间,有新windows推出的时候,增加了FUNCA和FUNCW,但是原来的FUNC还在。 然后又随着更新版本的windows推出,增加了FUNCEXA,FUNCEXW,但之前那些不带EX的还在。 然后在某一个版本又增加了SAFE_FUNCEXA,SAFE_FUNCEXW,之前那些还在。 其实这些函数的功能都几乎相同。。。。这样的函数还有几百个之多,只能说这个屎山堆得极高 |
因为微软不会修改底层的api,但是微软它会它会造新的轮子,那就是造新的api。 你想那什么mfc winform wpf 基本上都是基于旧的win32api来进行封装的。 在这个过程中呢,如果有旧的api满足不了的情况,那么微软他不会把这个旧的api给它删除或者改掉。 即使旧的api可能满足不了新的应用,或者旧的api设计存在问题,但是为了保持向下兼容性微软并不会把这个旧的api给它改掉,而是增加一个新的api,这个api的名字在后面加上一个后缀。 这就是保持向下兼容的非常关键的地方,这个api设计问题我不会说直接把它改掉,而是呢再增加新的api。 讲的详细一点,比如咱们调用这个selenium吧,他这个selenium2和selenium3他的这个api就不一样,啊,那在微软它实现的时候它会增加新的这个api,也就是说selenium3和selenium2的api同时存在。 这样肯定就是变得复杂,然后包的体积变大,但是呢它兼容啊,你比如说你之前用selenium2写的这个程序,你及时导入这个selenium3的这个库,因为selenium2的api没删除没改动,你这时候你可以直接使用,这就是他好的地方。 否则的话,原来代码你必须得通通修改一遍,然后重新编译别人才能够使用。 要不然那你原来的旧程序它依赖底层系统的这个api已经删除或者改动了,那么这时候你这个旧程序它就没有办法使用了。 送礼物 还没有人送礼物,鼓励一下作者吧 |
不是用了什么技术 而是始终没有删除历史的屎山 上古时期的各种api, 带着这些api莫名其妙的调用逻辑和bug一直延续至今没有删除, 所以基于上古屎山的操作系统写的上古屎山应用程序, 还都能跑起来 就是苦一苦码农了, 只能在屎山边上堆新的屎山 |
新系统用新API,旧API不删,攒多就这样。 有个反面例子就是暴雪公司的魔兽世界,每个新版本都改动一大堆API,比如像是: 旧版 GetAddOnMetadata(AddOn,"Version") 新版 C_AddOns.GetAddOnMetadata(AddOn,"Version") 看着变化不大,就加个前缀,如果这时你的插件仍然用旧版API会怎样?会报错,会无法运行。 暴雪每个小版本都会改一小堆API,每个大版本则改一大堆API。所以每逢大版本的交替时节,你都可以在插件站的评论、暴雪官方论坛、曾经与魔兽无关的魔兽贴吧、NGA论坛和插件整合包作者留言板里看到大量用户抱怨为什么插件不能用、为什么插件不断报错(友善些催促更新,坏些的甚至谩骂)。 插件更新修改并不是点点鼠标就能完成,稍微复杂插件用到的API往少了说有1000多条,往大了说仅一个主文件就会有几千行,还不包括其他LUA文件和子目录内容。加前缀这类的修改还轻松些,做好定义就能应付,若插件需要的一部分API被废弃,那么意味着原本功能完全失效,必须用其他API或者干脆完全没相关API可用。 这也是为什么每年都会有插件被废弃,从1.0到9.0能看到许多优秀的插件在不同时间线停止更新,原因或是作者不再玩魔兽,或是作者嫌工作量太大懒得再改,或是原API废弃导致插件功能无效而被迫放弃。 暴雪这样做的好处就类似于苹果,通过废弃旧API,统一归类来减少漏洞,保证可用插件API的一致性、整洁性和安全性,缺点就是插件作者和玩家经常骂街。复杂点的插件一旦停更,一两年后往往就彻底无法启用,要么等其他人复活,要么找替代,要么放弃。不像Windows,Win10系统仍然能打开一部分00年代90年代软件或游戏,只要旧API尽可能不删除不修改,那么兼容性自然就提高了,也就是所谓的“向后兼容性”了。反过来如果暴雪从初版开始所有旧API不删不改,每个新版新功能用新API,那么2版的旧插件仍有很大可能可以使用,当然代价就像Windows,代码越来越臃肿,问题越来越复杂,自动外挂越来越千奇百怪。 两种做法没有绝对的好与坏,弃旧API方便了官方管理和系统安全(暴雪或苹果),维持旧API方便了用户使用(微软),出发点不同而已。 |
我不得不承认,尽管windows每一个版本都有n个bug,但是这个兼容性不要太好 支持32位系统就蛮贴心的,不像隔壁macos,说砍32就砍32,就挺秃然。。。还有还有当年勒索病毒的时候,微软给xp也打了补丁 (跑题了啊,就这样不正经地回答问题吧) 简单点说,就是微软这么多年也没怎么砍内核,依旧支持很老的32位应用,哪怕是edge换了一个谷歌内核,也不忘记加一个IE的兼容模式(还是这句话,某果该学一学咯) 第一次在知乎回答,不喜勿喷哦 |
核心原因就是对Win32 API的坚守,然后保证古早软件对Win32 API的调用在语法和语义上不出问题。 保障语法不出问题只需要保证ABI稳定。不要乱删乱改就好了。 保障语义不出问题就要有意做一些技巧性的蒙骗,来骗过那些古早软件。比如一些重要路径和一些注册表位置,新版本系统会做一些重定向来保障旧的的可访问性。比如DLL匹配,VS会用一些清单文件,或者直接编译到二进制中,来路由DLL的调用,保障旧软件在新系统上能调用到合适的DLL。 微软每次想整点新技术,就会脑袋发热说以后不维护Win32 API了。结果到关键时候,头脑又清醒了,Win32 API还是当祖宗供着。 成也Win32,败也Win32。 正是因为Win32的成功,导致Win32之后,Windows上面再也没有出现过能打又能被普遍接受的新API接口。 后面推的几波API,没有一个好命的。都以为Win32这下要被新API取代时,最后噶的总是新API。Win32这个老祖宗没人敢动。后面推的几波新API不是直接不维护了,就是沦为了微软家的UI框架,而不是Windows API。 扯COM的有点扯,这东西就没几个软件会用,尤其是普通开发者更不会去用这玩意。而它的主场,VB和IE都作古了,官宣死亡。微软自家软件都在慢慢抛弃这东西,VS Code直接用的Google家的框架搞的。Office也在慢慢脱身,内置脚本语言去拥抱Python了。 Win32 API才真的是Windows软件大厦之基石。各种UI框架,基本上也只依赖Win32 API。旧框架封装Win32的控件。新框架控件自己画,只依赖Win32的窗口和消息机制。 只要Win32 API不噶,Windows能兼容到天荒地老。 同样,只要Win32 API出点小事,那兼容性也会立马就崩掉。就是你用的跨平台框架也一样立马崩掉,因为这些框架就独独依赖Win32 API。 |
万仞屎山 更高一尺的技术 别小看这个技术 一般公司还没摞到一半就塌了 |
linux 既不鼓励静态链接(参考lgpl),程序自带动态库的话(变相绕开lgpl)链接时候的选项又很反人类(Multiple glibc libraries on a single host这个不错 )。这自然就反衬出win的前向兼容能力很强啦。 当然盖茨当朝的时候,也确实愿意花时间和金钱为应用软件做兼容甚至为了让有bug的流行软件不崩溃愿意改内核。windows编程启示录中甚至披露:win95本来是win93的。 |
靠承诺 其实也是可以像别家厂一样甩包袱的,但那样就太不微软了,所以定下的接口规格都承诺兼容很久,不是说砍就砍的,只要你严格按照的规范开发,很少遇到不兼容 当然各种调用私有接口,硬编码写死的骚操作就不保证了 至于技术上到底怎么实现兼容旧标准又提供新标准,可以看看下面的说法 Demystifying Shims – or – Using the App Compat Toolkit to make your old stuff work with your new stuff |
推荐一本书,the old.new things,作者的博客还在维护,这老哥是微软公认的兼容性专家。 |
我觉得PE的设计对Windows兼容性的影响有着不可磨灭的贡献。只是硬盘占用大了点。 你试试linux塞进去辣么多.so?而且不同模块调用的动态库版本还不同?绝对崩得你死去活来 |
1. 微软公司在开发Windows NT 4.0时,作为ARC会员参与MIPS阵营,积累了丰富的C语言移植经验。促成了Windows跨平台的Bootloader标准化设计,并为后来的UEFI技术奠定了基础。 2. 内核采用真正组件化的硬件抽象层,驱动程序API比较稳定,采用如WDDM这样的稳定API,使得内核小版本更新时,大部分旧版驱动程序能够继续使用,从而提高了系统兼容性。这相当于Linux的DeviceTree和*.ko内核模块。 3. 子系统技术,理论上可以支持包括Win32在内的无数个子系统。例如容纳Posix子系统、Android子系统等。 4. WoW64是Windows的一个子系统,它为现有的32位应用程序提供了一个32位模拟层。使得大多数32位应用程序能够在64位Windows系统上无需修改即可运行。 5. COM组件对象模型技术具有语言无关、接口继承、线程模型、自动发现、版本控制等特点,为不同软件相互调用提供强大支持。微软在COM的基础上设计了.NET平台。 6. SideBySide Assemblies 技术,通过自动隔离不同进程中存在差异的动态链接库,实现软件新旧版本、不同版本共存。 7. Component Store 组件存储,即WinSxS文件夹。它搭配SideBySide Assemblies,保存了从Windows 95到最新版本所需的各种DLL文件。在必要时系统可以加载旧版的DLL,以确保兼容性。 8. Application Compatibility Toolkit,专门设计的兼容性平台,为数以万计的陈旧软件设计了应变策略和内存补丁,实现了自动加载并且无需用户干预。 9. Hyper-V 虚拟化技术,在单个物理机器上运行多个操作系统实例。每个实例都能够独立运行不同版本的Windows或其他操作系统,典型案例如Xbox游戏机。 10. Driver Isolation 驱动程序隔离,典型如WDDM 2.0版本,可以把某些驱动模块移出内核态。允许Windows隔离有问题的驱动程序,以防止它们影响系统的稳定性。 |
Windows 系统的动态链接是系统基础功能,而不是由 libc 实现的。 结果就是,同时使用多个 libc 在 Windows 是很稀松平常的事情。 Windows 每个层次都有自己的 libc,甚至 ntdll 都有一个,libkcrt 项目就整理了 ntdll 导出的 libc 符号: 同一个进程上多个 libc 共存也不奇怪。只要别在动态库边界之间传递 libc 的数据结构 (比如 FILE*),大体上都可以相安无事。微软自己的 msvcrt/msvcrXX/ucrt 就不提了,微软会保证它们能共存。cygwin.dll 里也带了自己的 libc,基于 newlib,丝毫不影响 Cygwin 程序调用 Win32 API 和其它 DLL。 但至今在 Linux 上,两个使用不同 libc 的系统,就是两个世界。两个 libc 共存在一个进程里近乎是不可想象的事情,甚至 musl 在静态链接 libc 的时候会自动屏蔽掉 dlopen 和 dlsym。 |
@叛逆者 :「内核中有对 1300 种硬件的 Workaround」 |
其实就是Windows NT,因为win系统的内核真是人家自己构建的,而且构建的十分前瞻,用了20多年还可以继续用,三大主流操作系统里,这是只此一家的,Linux发行版的内核是开源的自不必多提,其包依赖关系太依赖于系统自带的包管理器的兼容水平;MacOS内核是free bsd的,不过虽然MacOS的系统兼容性垃圾,但是架不住人家的用户(果粉)的兼容性好啊 |
微软不会重复造通用软件或者系统软件这类轮子。 看微软文档,实际上WindowsNT到现在都是用Windows2000的设计作为基础,常用的Win32 API大概率是Windows2000就有的,包括C语言基础设施/窗口管理/进程线程等等(作为一个)操作系统(而不是仅仅是内核)应该提供的基础API。而新的API通常会以增加参数的方式提供更灵活的功能。Win32的开发风格可以说是先确定我们有什么,够不够用,不够用那么添加一个新的API。 WindowsVista时期微软开始完善COM,到Windows8为止积累了足够多的经验,带来了WindowsRuntime,这套设计一直用到现在Windows11。内核和Win32是稳定的,这一系列框架基于Win32,那么就是稳定的,因为操作系统的功能不依赖这些框架。 而Linux这边完全看维护者或者商业公司的喜好,基础设施从来就不统一,开发操作系统基础设施这类软件不能盈利,没有足够的人手,加上Unix的有毒的KISS哲学,导致这些软件都不够完善不够好,互相内斗。哪天有个人写了个新软件,然后维护发行版的人看上了,觉得好,就把之前的方案丢了换成新的。这就是GNU和Linux的困境。我在网上接触过不少在微软工作20年甚至30年的员工,他们10年20年都是负责的一个模块,因此也不存在完全抛弃以前的设计从0开始的动机。 |
一坨伟大的屎山。 毕竟大量工业,农业,各个领域都或多或少用windows系统。 工业设备很多都成老古董了还在用,并且几十年不换。工业软件也是更新极慢 比如某个工业软件需要在w7上运行,怎么办,w10系统上弄个w7虚拟机。 假如需要远古w98怎么办,w10系统上套个w7,然后w7上套个98 至于16位,8位的怎么办,w10系统上继续套呗,或者企业也倒闭了 |
因为真有旧版windows,微软甚至为了兼容旧版dos windows,做了很多从文件格式到加载运行到底层环境模拟的黑科技兼容,而不是简单的把dos替换成windows,win3替换成win11 |
可能是因为msdn的编辑把deprecated这个词屏蔽掉了…… |
公司的商业文化使然,微软为了套牢客户对软件兼容性近乎偏执。 当年微软第一款获得成功的视窗操作系统是Windows 3.0。其实还不是一个严谨的系统,而是DOS上面加了一层GUI的皮,但是在PC平台上很受欢迎。后来下一个版本的WINDOWS 95才更接近一个完备的视窗系统。在推出WIN95之前微软对当时的热门软件进行了一系列测试,要求WIN 3下能运行的热门软件在WIN95上也可以。 很快测试部门发现了问题:有一款模拟游戏SIM CITY在Win95环境下会崩溃。调查发现是游戏自带的BUG:SIM CITY显然有指针错误,使用了已经释放的内存。这种BUG的后果看人品,在Win 3下侥幸没事,在Win95下会崩溃。 微软决定哪怕是别人的错也要为他们擦屁股,以确保大票SIM CITY的玩家愿意升级到WIN 95,于是在注册表中一顿HACK,让SIM CITY即使有指针错也不会在WIN 95下崩溃。这就是为什么微软的注册表一直像个垃圾堆,哪怕是新装的系统注册表里也有一大堆不知所云的内容,里面都是各种微软背地里的HACK,和开源LINUX完全是两种思路。 HACK太多了,导致尾大不掉。以前从微软裸辞的一个大牛抱怨过,曾改掉系统里一个BUG,但是被上级告知不许碰,就要留在里面。他据理力争被否,然后愤而辞职。这些BUG背后都是微软积累的各种HACK或者为了CIA、NSA留下的后门,动不得。HOHOHO 为啥现在中国政府机关开始去微软化,就是怕这些HACK。其实微软允许中国政府看其软件代码的,但咱们实在不放心。 |
|
[收藏本文] 【下载本文】 |
科技知识 最新文章 |
百度为什么越来越垃圾了? |
百度为什么越来越垃圾了? |
为什么程序员总是发现不了自己的Bug? |
出现在抖音评论区里边的算命真不真? |
你认为 C++ 最不应该存在的特性是什么? |
为什么 Windows 的兼容性这么强大,到底用了 |
如何看待Nvidia禁止使用翻译工具将cuda运行 |
为何苹果搞了十年的汽车还是难产,小米很快 |
该不该和AI说谢谢? |
为什么突破性的技术总是最先发生在西方? |
上一篇文章 下一篇文章 查看所有文章 |
|
|
股票涨跌实时统计 涨停板选股 分时图选股 跌停板选股 K线图选股 成交量选股 均线选股 趋势线选股 筹码理论 波浪理论 缠论 MACD指标 KDJ指标 BOLL指标 RSI指标 炒股基础知识 炒股故事 |
网站联系: qq:121756557 email:121756557@qq.com 天天财汇 |