是什麼造成了 Windows 兼容性問題?

每一次Windows新版發布就會有人提出新版兼容性很差的說法,比如至今有玩遊戲win7最好的說法,但是是什麼造成了這種問題?這種說法又是不是合理的?

我的想法是(如果有錯請指出):一個編譯之後的程序裡邊,有些是程序本身的代碼編譯出的機器碼,這部分應該不牽涉操作系統的問題,只要CPU指令集兼容即可;另外還有鏈接的操作系統的函數之類的,如果系統不改介面定義,也應該能正常執行(再順便問一下,Windows的兼容模式是否與此相關)。那麼是什麼造成了軟體兼容問題?

另外,一些破解補丁或者病毒等不正常的程序在新系統可能不能正常運行的原因是什麼?


一般都是系統API的行為改變了造成的。不同版本的win,API的實現可能完全不同。如果沒測試好兼容性,就可能出現程序的兼容問題。而且,大部分時候其實是app的問題。

舉幾個我遇到的例子。

1. 某國產著名下載軟體,一開始在vista上只要一選擇下載目錄就crash。結果是SHBrowseForFolder的參數結構體中的某個變數沒有清零。xp不管這個,vista+開始用這個變數,結果就crash了。加上ZeroMemory解決。

2. 我的引擎KlayGE,幾個月前發現在Win10上滑鼠輸入不正常,無法響應按鍵釋放。後來發現原先WM_INPUT里的設備句柄總是等於枚舉時候的句柄,Win10+變成另一個句柄值。MSDN上確實也是那麼說的,以前能用只是運氣好。照著改後恢復正常。

3. Quake 2,一開始在xp上運行不正常。原來代碼里判斷os版本號的時候,只考慮了95/98/2k等。把==改成&>=後恢復正常。

4. 解謎遊戲《不可思議的機器》,在xp上有一關用官方答案也過不去。原因在與xp上計時器精度提升到1ms,而不是95/98的16ms。而遊戲是照著16ms調的時序,就不行了。

更慘的情況可能是有些app的bug,但因為app實在太流行,它們即便改了用戶也不一定會更新。這時候只能把系統改成順應那個bug。一個典型的例子就是DivX Player。它在調用DX的時候lock了紋理的一小部分,卻寫入了整張紋理。結果知道現在,DX runtime的代碼里仍然有判斷DivX Player的代碼,如果遇到是它就總是lock整張紋理。


向來是程序兼容系統,不是系統兼容程序。每個軟體都有個支持的操作系統列表,比如暴雪的星際爭霸支持Windows 95 98這樣,這代表開發者承諾軟體在這些操作系統上可以跑。軟體開發的時候,不可能兼容還沒開始動手寫的操作系統(如果有軟體宣稱自己兼容Windows 11現在就可以刪掉了),所以如果在程序開發者不支持的Windows版本上運行出現兼容性bug是正常現象。

為了最大化向後兼容性,微軟有一套和開發人員的合同,叫做Windows API的就是。微軟在升級操作系統的時候,會盡量保證API仍舊可以正常工作。至於API之外的未公開細節,即使是在微軟網站上發布過,只要沒進Windows SDK文檔,微軟並不做任何兼容性上的保證。比如IE在7.0之前是每個頂層窗口一個頁面,IE7引入標籤頁之後就不是了。繼續兼容那些假定IE窗口結構永不會變化的程序會阻止IE的改進。病毒和殺毒軟體這樣底層的東西,因為依賴的就是這種未公開的實現細節,操作系統沒有可能去做兼容。基本上,只要使用了未公開的實現細節,軟體就有在下個禮拜二的補丁日掛掉的可能。為了避免過於經常出現這樣的問題,微軟通常是在主版本或者服務包升級的時候才做這種比較大的實現細節上的更改。對於程序員來說,應該盡量避免依賴於這樣的實現細節,能用API就用API。

對於銷量很大而用戶忠誠度很高的軟體中的影響用戶升級的軟體bug,微軟提供兼容模式,模擬舊版本的Windows的部分行為,作為面向最終用戶的臨時解決方案。但是微軟不可能一直這樣慣著有bug的程序,這對提高整個生態環境中的軟體質量沒有幫助,比如不必要地要求管理員許可權的程序造成用戶較難不用管理員身份登錄系統,增加用戶被攻擊的風險。兼容模式只針對開發者不願意或者無法提供升級的場合,而且並不能解決所有的兼容性問題。

真正的兼容性問題的解決方案是軟體作者開發個兼容性補丁,宣告自己的程序對新的系統的支持,例如Visual Studio 2005 Service Pack 1 Update for Windows Vista或者暴雪發的星際爭霸補丁這樣。對於病毒和殺毒軟體這樣底層的東西,基本上每個操作系統升級都會出問題,要升級一下才能支持新的系統。本來驅動程序也是這樣每個操作系統升級都要出個補丁,因為DDK一直是升級的時候可以隨便加減API參數這樣,但是後來驅動開發者也開始向微軟要向後兼容性了……

XP和之前系統中流行的兼容性bug:

  • 直接訪問顯存
  • 在程序中檢測操作系統版本,如果不是Windows 95或者98則拒絕運行
  • 在程序中檢測操作系統版本,如果不是Windows NT 4則拒絕運行
  • 在程序中檢測操作系統服務包版本,如果低於2則拒絕運行(Windows 7到現在都沒出過SP2……)
  • 沒有預料到用戶可以用主題自定義界面風格,造成計算窗口元素坐標的時候出錯
  • 沒有預料到系統目錄不叫System叫System32,比如用WinG寫的遊戲
  • 沒有預料到顯示器沒有提供256色的顯示模式

  • 沒有預料到連續兩次調用timeGetTime會返回同樣的結果

  • 沒有預料到系統附件(比如defrag,Active Movie)程序的更改

  • 寫入剪貼板的時候忘記先清空
  • 寫入剪貼板的時候寫錯了數據,比如把高彩圖像當作真彩圖像傳給系統
  • 從堆中釋放了內存,然後去訪問自己釋放的內存
  • 嘗試寫入只讀位置,比如系統目錄下的ini文件
  • 用16位變數保存32位的系統句柄
  • 釋放了DLL,之後調用DLL裡面的函數
  • 沒有預料到空閑的磁碟空間會大於2GB

  • 顯示Message Box的時候忘記把對話框移動到前台
  • 沒有預料到文件路徑可以包含多位元組編碼的文字
  • 服務之間循環依賴
  • 以為當前用戶一定是管理員

Vista和之後系統中流行的兼容性bug:

  • 在程序中檢測操作系統版本,如果不是Windows XP/Vista/7 則拒絕運行
  • 使用InstallShield編寫的安裝程序假設運行安裝程序的用戶是管理員

  • 假定用戶目錄在Document and Settings下
  • 安裝服務時設定依賴項為一個只存在於舊系統的服務。
  • 在程序中檢測系統DirectX版本,如果不是9則拒絕運行
  • 嘗試關機或者重啟,但是忘記啟用許可權
  • 錯誤地統計了對SHGetDesktopFolder的返回值的引用計數

  • 以為當前用戶一定是管理員
  • Google Chrome以為某個系統DLL的地址一定低於4GB

  • 在沒有許可權的時候試圖創建全局內核對象
  • PopCap一些遊戲在低檔顯卡中的圖像拉伸問題

  • 以為系統內一定有一些編碼解碼器
  • 訪問服務管理器卻不先啟用服務管理器許可權
  • 32位程序訪問64位驅動
  • 以為IE沒有標籤頁支持
  • 讀取設備名的時候沒有分配足夠的緩衝區
  • 試圖刪除被系統保護的文件

比較不流行的兼容性bug

  • 有API不用去翻註冊表(http://blogs.msdn.com/b/oldnewthing/archive/2003/11/03/55532.aspx)
  • 依賴於WM_PAINT來運行業務邏輯(http://blogs.msdn.com/b/oldnewthing/archive/2006/03/27/561924.aspx)

  • 以為NTFS不會有新版本,以及以為編譯器一定會把基類按照某個順序編譯。(http://blogs.msdn.com/b/oldnewthing/archive/2003/12/23/45481.aspx)
  • 以為資源管理器的窗口類名是Cabinet-WClass
  • API設計的時候就有問題,沒有考慮支持64位系統(比如ADO和撥號的API)
  • 提供API的組件被砍掉了(比如Outlook Express)
  • 提供API的組件還在但是要求更高的安全性(比如IE的ActiveX支持)
  • 通過不斷分配內存的方式來檢測系統內存大小(在有虛擬內存的機器上會造成系統穩定性問題)
  • 在有多線程/多進程執行序競爭的場合,沒有等待其他函數的完成執行。


微軟:

我不向前兼容,用戶噴我兼容性差。

我向前兼容,開發者就繼續不思進取用老方法把程序寫成一坨shi,然後掛在新系統,用戶繼續噴我兼容性差。

我能怎麼辦,我也很絕望啊!

列舉下老代碼怎麼寫出一坨shi吧:

1. 檢測操作系統版本靠字元串匹配,據說這是為什麼不用windows 9這個名字的一個顧慮。

2. 以為系統目錄一定叫system,用戶目錄一定叫documents and settings,程序安裝目錄一定叫program files。

3. 以為用戶一定是管理員

4. 修改註冊表中時非要硬編碼註冊表路徑。

5. 不支持sp3以下系統版本。(win7:喵喵喵?)

6. 指針可以free任意多次,這不是bug,這是feature!(微軟曾經修復過,然後噼里啪啦死了一大堆程序,於是把這個「feature」加了回來)

7. 以為kernel32.dll里的api永遠有效。至於msdn沒寫?who care?老子水平好,寫代碼從來不看文檔。

8. 以為裸寫顯存效率高性能好,並引以為豪。

等等等等……


針對 @叛逆者 的答案作個補充:

還有有些時候是用了些依賴特定條件的奇技淫巧:

我以前的工作單位有一個產品出現過只能在 32 位 Windows 上正常使用的情況,後來發現原因是某黑產出身的同學該用 GetCommandLine 的時候沒用 GetCommandLine,而是直接把進程空間內的某個地址當字元串指針進行讀取,結果到了 64 位的 Windows 上這個地址變了……


古時候曾經有一次,Windows的新版本決定說,內存free(不是指free函數)掉之後訪問立刻AV。然後模擬人生就傻逼了。於是Windows對模擬人生的兼容性又進一步下降。


windows的兼容性問題是因為windows10還能運行10多年前就停止更新的軟體。你看widnows mobile10就沒人罵兼容性問題,它還能運行windows mobile的軟體不?


說Windows兼容性差?

macOS Sierra教你做人。


你說的兩個問題,破解補丁 和 病毒 就我來給你講解吧

首先要了解破解補丁是怎麼工作的?

所謂的破解補丁是在軟體註冊演算法代碼區域里,改了關鍵指令,讓註冊軟體,無論你輸入什麼都返回成功註冊。那我們就要我們的破解補丁找出那個關鍵代碼,方法是從關鍵指令處附近提取特徵碼。

破解補丁會先掃描要破解的軟體二進位代碼,搜索特徵嗎 加上 文件偏移 就找到了關鍵指令處然後修改保存重新生成破解後的軟體,當然還要備份源程序,這就是破解補丁的工作方式。

而作者每次更新軟體,如果更新的功能比較多,編譯之後二進位代碼發生了大的變化,破解補丁就找不到了那個特徵碼,這跟破解者技術高低運氣都有關係。如果破解者找到的特徵碼是作者永遠不會改變,或者是編譯後不會影響破解補丁效果的,那麼這個破解補丁永久有效。這叫萬能補丁,當然這種情況很少,除非作者不更新了,要麼就是傻*。

再說說病毒,病毒調用的API不會很多,而且大部分模擬或使用不公開的API,這樣肯定兼容性變差了,因為不公開的API,不一定下一個操作系統上還會保留著,畢竟他不公開。還有操作系統一般還是向上兼容的。那麼問題來了,病毒還是無效,那麼就是許可權的問題了,Windows xp跟windows 7 就是例子,兩個操作系統在許可權上做了很大調整,比如UAC在xp上是沒有的。


怎麼都在想找機會把windows批判一番呢?

windows上不兼容是很罕見的事情

至於其他的os嘛,

反正ABI和API都會變的某os表示:

你們既然都有header和source的,早點跪安然後回家去改code吧


windows的前向兼容導致了windows的兼容性問題。

不能運行就不會有兼容性問題,因為根本不存在兼容。


怪操作系統的都是那些懶。。或者沒實力的。。或者店大欺客的APP製作者,廠家等等。。

舉個例子。。暴雪的遊戲從來不會因為XP還是vista,還是win7,8,10而出現什麼不能玩。。

而騰訊的垃圾遊戲。。win8更新8.1也能出現不兼容。。由此可見。。騰訊對廣大用戶多麼不重視。。

所以。。造成種種不兼容的情況都是軟體開發商的懶惰或者不重視。。。


某個軟體主流版本號是11甚至12

但是用人單位只能給你提供4,6

過去甚至還有3給你用.

你敢升級到win10?

我見過N多同事買了電腦以後被迫裝回32位XP或者32位WIN7的.


你說的是奇葩疼訊吧?蛋疼的TP


vista 的時候卡過一次!其他時候還好!

不過新版軟體體驗太差了,不能無縫或沒bug 使用!


windows已經是世界上兼容性最好的os了。一個win10系統,可以安裝在三四年前的電腦上,也可以安裝在最新的電腦上。安裝在八寸的atom的系統上也可以安在外星人這類高性能系統上。可以兼容各種硬碟,ssd,內存,codec,各種介面,各種尺寸。從一線oem,到深圳山寨小廠的設備都可以開機運行。還不怎麼藍屏。

其他哪個系統能做到?


與其說win的兼容性不如說說蘋果的更新吧

每次蘋果發布版本更新,不管是電腦,筆記本,pad,手機,都會有一大堆一大堆的人在那裡發帖問,更新了嗎?有問題嗎?我的是xx版本可以更新嗎?等等等等,彷彿蘋果的更新是一件需要非常小心翼翼的事情

這讓我懷念起用諾基亞的時代,手機買來什麼樣,到死就是什麼樣

隨著智能化的發展,我們的設備彷彿有了它的生命進程

兼容性這個問題只要是硬體和軟體同時出現就一定會存在,windows的兼容性越來越差了?

不!實際上是我們更關心兼容這個話題了,在最輝煌的xp時代,因為兼容性導致的問題比現在少嗎?不!那個時候不明所以的問題比現在多太多了,不然為什麼會有那麼多的系統優化軟體和第三方補丁?不過是那時候我們還小,沒有兼容性這個概念,刷新重啟換機子幾乎能解決一切

現在呢?我們長大了,對事物有了更清醒的認識,你開始苛責問題的出現,並且試圖用門外漢的腦迴路來解釋問題,當你不能解決,抱怨就產生了:win系統的兼容性怎麼越來越差?


不是應該由軟體商兼容新舊os嗎?啥時候這個規則反過來了?!

很多軟體商就是被微軟慣壞了,看看人家mac,mac os 9的應用到os x壓根就跑不了,又怎樣?又怎樣?又怎樣? Jobs就這麼牛,他贏了。


win10兼容性已經非常好了,我現在用win10依然能運行至少10年以前的遊戲,生化危機2,合金裝備1,帝國時代1,cs1.6

你覺得兼容性不行,你可以試下mac,別的不說,就當年蘋果從ibm的處理器轉為英特爾時,一堆軟體資源就廢了


哦,10年前的說法應該是 玩遊戲 WINXP最好 (狗頭


excuse me? Windows的兼容性是市面上能找到的最好的了。ABI級別的兼容。這也是為什麼這麼多工業級別的系統用Windows的原因之一。


推薦閱讀:

Windows 10 默認輸入法使用 Shift 切換中英文是合理的設計嗎?
win10中文輸入法為什麼會妨礙遊戲正常運行?
為什麼我感覺用win10電腦變快了?
win7升級到 win10後wifi連接受限?
電腦中了360,怎麼辦?

TAG:MicrosoftWindows | 操作系統 | Windows10 |