更多 Wine 所不能做的
看完 Wine 的可用性問題后,現(xiàn)在讓我們來總結(jié)在嘗試使用 Wine 時一些常見的技術(shù)問題。
缺少 DLL,這可能是最常見的問題:很多安裝由于缺少 DLL 而失敗。人們應(yīng)該熟練使用調(diào)試器來決定下一步如何去做。(稍后將深入討論調(diào)試器)。
DLL 版本問題
一些安裝程序在開始之前會檢查現(xiàn)有的系統(tǒng) DLL。Wine 解決這一問題的方法是,創(chuàng)建假 DLL 以滿足安裝程序的需要。不過,有一些安裝程序會更進(jìn)一步并深入檢查 DLL 以獲得它們的版本。這對假的 DLL 來說要求太高了,會導(dǎo)致安裝失敗。
DLL 加載次序
Wine 有對很多 Windows DLL 的實(shí)現(xiàn),而且如果可用,它還可以使用原始的 Windows DLL。如果兩種 DLL 都可用,好像顯然應(yīng)該選擇總是使用 Windows 自己的 DLL,但實(shí)際上 Windows DLL 有時會包含不能被滿足的依賴。要確定是更應(yīng)該使用 Wine 的 DLL 還是應(yīng)該使用本機(jī) DLL,惟一的方法是,基于各個應(yīng)用程序反復(fù)進(jìn)行試驗(yàn)。
DLL 中的函數(shù)
當(dāng)一個 Wine DLL 沒有實(shí)現(xiàn) Windows 中相應(yīng)的 DLL 的全部功能時,應(yīng)用程序可能會遭遇函數(shù)調(diào)用失敗。由于 DLL 是動態(tài)加載的,可能沒有辦法事先知道會發(fā)生這樣的事情。這是一個復(fù)雜的問題,有一些可做的工作,但最終實(shí)際來說它只是取決于應(yīng)用程序的代碼如何編寫。
有一些因素會減輕這些問題。一方面,您將會一個一個地遇到這些問題,而不是一次遇到全部問題,這樣處理起來要容易些。另外,您遇到的那些問題可能其他人曾遇到過并已經(jīng)解決(而且解決方案已經(jīng)公布出來)。Wine 用戶組非常活躍,會提供許多幫助,每周一次的 Wine 時事通訊(參閱 參考資料)是極好的信息資源。
Wine 中還沒有實(shí)現(xiàn)的 Win32 API
在 Wine 中,很多 Win32 API5 的函數(shù)是殘缺不全的。最常見的原因是,相當(dāng)多的 Win32 API 并沒有被文檔化。這就意味著一個特別的應(yīng)用程序可能會調(diào)用某個函數(shù),而完全沒有關(guān)于此函數(shù)的可用資料。例如,我們在運(yùn)行一個簡單的 RPC 程序時發(fā)現(xiàn)了 RtlAnsiCharToUnicodeChar 這個函數(shù)。在 MSDN 上的搜索結(jié)果顯示沒有關(guān)于這個函數(shù)的資料,而且沒有關(guān)于所有 RtlXXXX 類別函數(shù)的資料。因此,如果它們在 Wine 中的實(shí)現(xiàn)對一些應(yīng)用程序來說至關(guān)重要,那么人們可能只有去猜測它們的行為了。
商用的 Wine
CodeWeavers 為 Wine 做了很多工作。多年來他們?yōu)?Wine 項(xiàng)目貢獻(xiàn)了很多代碼,他們出售商用版本的 Wine,其改進(jìn)的用戶界面解決了我們在本文中提出的很多問題。
例如,CodeWeavers 的二進(jìn)制安裝文件會在用戶的開始菜單中添加一個 Crossover 條目;安裝后,絕大多數(shù) Crossover 相關(guān)的任務(wù)可以通過開始菜單條目來完成。在開放源代碼的 Wine 中,所有這些任務(wù) -- 安裝、程序執(zhí)行以及其他任務(wù) -- 都必須在命令行中執(zhí)行。此外,CodeWeavers Crossover 將會嘗試去為新安裝的軟件包配置一個合理的默認(rèn)值,如果需要的話會在安裝完成后自動重新引導(dǎo),并以其他形式減輕用戶的負(fù)擔(dān)。
CodeWeavers 使用開放源代碼的 Wine 作為他們的 Crossover 產(chǎn)品的基礎(chǔ),所以,除非遇到上面我們討論過的可用性問題,否則,在其中一個產(chǎn)品中能運(yùn)行的應(yīng)用程序,在另一個產(chǎn)品中同樣也能運(yùn)行。要深入了解 CodeWeavers 和 Crossover,以及要獲得可以在 Wine 上運(yùn)行的應(yīng)用程序列表,請參閱在 參考資料中列出的鏈接。
應(yīng)用程序安裝分析
由于 Wine 支持 Windows 可執(zhí)行文件的運(yùn)行,您會想當(dāng)然地認(rèn)為可以使用程序的安裝程序從頭安裝,這是正常的。不幸的是,幾乎不會那樣。對 Windows 安裝過程的理解將有助于解釋原因。下面非常簡單地描述了 Windows 安裝程序通常要做的事情的(不必是這個次序):
將文件拷貝到一些目錄。
注冊 DLL,并將其他應(yīng)用程序相關(guān)的信息添加到注冊表中。
在安裝過程中,有時會檢查 DLL 的版本(如前面所提到的)。
修改 INI 和一些其他配置文件。
因而,Wine 會遇到兩種類型的問題,必須按順序解決:
安裝過程中的問題。
執(zhí)行過程中的問題。
在調(diào)試 Wine 安裝的過程中,如果您同時有一個可用的 Windows 系統(tǒng)的話會非常有幫助。那樣,您可以對 Windows 安裝使用追蹤器以確切斷定哪些文件被拷貝,哪些注冊表?xiàng)l目被添加或更新,哪個 INI 文件被修改,等等。記錄安裝步驟的順序并與失敗的 Wine 安裝相比較,是故障診斷的好向?qū)А?
在 Linux 上安裝 Wine
如果您正在使用 Red Hat 或者 SUSE,最簡單的方法是從 CD 安裝 Wine。不過,如果那些 CD 比較老,您可能需要通過源文件安裝,因?yàn)?Wine 項(xiàng)目經(jīng)常更新。如果通過源文件安裝,您會發(fā)現(xiàn) Wine 用戶指南(參閱 參考資料以獲得鏈接)是一份價值無法估量的資料。簡化的安裝過程如下:
解開源文件后,切換到 tools 目錄下以用戶身份運(yùn)行 ./tools/wineinstall。
在 tools 目錄下運(yùn)行 winecheck 腳本來檢查安裝。您可能不會獲得 100% 的成功,但只要沒有關(guān)鍵問題就行。
Wine 的所有配置都保存在 ~/.wine/config 文件中。這個文件很容易理解:它描述了您希望將 Linux 文件系統(tǒng)的哪部分看作是 Windows C 驅(qū)動器,以及 DLL 的加載次序等其他的細(xì)節(jié)。
您應(yīng)該可以快速進(jìn)行了。例如,要安裝 WinZip 8.1,您可以下載安裝程序并在命令行中運(yùn)行 wine winzip81.exe 。
快速瀏覽一下可以了解很多內(nèi)容:您可以看到 WinZip 在運(yùn)行,它的文件瀏覽器組件顯示出熟悉的 Windows 驅(qū)動器 C、軟盤驅(qū)動器 A、一個 CD-ROM M 以及另外的 Z 驅(qū)動器。您可以猜到,所有這些都映射在我們上面提到的 ~/.wine/config 文件中。下面是文件中與 所示驅(qū)動器有關(guān)的片斷:
清單 1. Wine 的配置文件
|
從這里您可以看到, M 驅(qū)動器實(shí)際上是 /mnt/cdrom;C 驅(qū)動器是 /home/aditya/aug14/3/c;等等。
Windows 應(yīng)用程序移植到 Linux 的一個例子
技術(shù)上講,使 Windows 可執(zhí)行文件在 Wine 中運(yùn)行并不是移植,但是經(jīng)常被認(rèn)為是移植。這也是測試一個應(yīng)用程序是否適合使用 Winelib 進(jìn)行移植的好辦法。要獲得關(guān)于使用 Wine Winelib 庫編譯來移植源代碼的資料,請參閱 參考資料中關(guān)于 Winelib 用戶指南的鏈接。
我們已經(jīng)整理了一個非常簡單的應(yīng)用程序,來說明 Windows 程序如何在 Wine 中運(yùn)行。程序創(chuàng)建了一個窗口;從一個 DLL 中加載了兩個函數(shù),有一些對話框。我們將繼續(xù)使用非常簡單的例子;作為實(shí)際應(yīng)用中的例子,我們非常鼓勵您用 MS Office 等大型應(yīng)用程序進(jìn)行同樣的嘗試。
同時,這個例子可以通過讓您體驗(yàn)代碼的運(yùn)行來入門。
運(yùn)行代碼
示例 DLL 的源代碼在 DLLCode 目錄中,使用 DLL 的源代碼在 callDll 目錄中。要運(yùn)行只需要將兩者(DLL 文件和可執(zhí)行文件)存放于同一目錄下,并運(yùn)行 callDll.exe 。winetests 文件夾中的 README.TXT 文件描述了如何在 Linux 上 Wine 中執(zhí)行那個二進(jìn)制程序。
如果您愿意,可以隨意打開項(xiàng)目文件并進(jìn)行修改。
DLLCode 項(xiàng)目正確編譯后,您可以在 Debug 文件夾中看到 DLLSample.dll 文件。這個文件是 callDll 項(xiàng)目所需要的。為了您的方便,DLLSample.dll 已經(jīng)存放于 callDll 中正確的位置。舉例說明的 callDll 中產(chǎn)生的可執(zhí)行文件的依賴;您可以使用 Dependency Walker 來查看其他程序的依賴(參閱 參考資料)。
比較
下面是對運(yùn)行于 Windows XP 上的和運(yùn)行于 Red Hat 的 GNOME 中的消息框(Message Box)視覺上的對比:
對應(yīng)于此的 C 代碼(callDll.cpp 中第 60 行):
MessageBox(NULL, "Wine test ending...", "", MB_OK);
這提出了一些有趣的觀察:
最明顯的觀察之一是,雙方都支持消息框的使用;這是將 Windows 調(diào)用有可能映射為 Linux 中相應(yīng)部分的因素之一。如果您在 Wine 源代碼中搜索 MessageBox,您可以找到說明文件,文件中詳細(xì)說明了哪些函數(shù)已經(jīng)被實(shí)現(xiàn),哪些被去除掉。
大小、字體、顏色和標(biāo)題欄以及其他可視元素繼承自底層操作系統(tǒng)設(shè)置的默認(rèn)值。
從本文中所包括的追蹤文件中,您可以看到這個函數(shù)是在 user32.dll 中實(shí)現(xiàn)的。如果您在文件中搜索字符串“Wine test ending”,您將更深入地理解到,當(dāng)您在做一些與在消息框中顯示字符串同樣簡單的事情時,幕后發(fā)生了多少事情。
既然我們已經(jīng)看過了一個 Win32 函數(shù),讓我們來看一下,當(dāng) simpleDLL.dll 中實(shí)現(xiàn)的我們自己的函數(shù)之一被調(diào)用時,幕后發(fā)生了什么。我們將展示追蹤記錄中的片斷來說明何時 simpleDll.dll 被加載,哪些函數(shù)被導(dǎo)出,在哪一點(diǎn) getTitle() 函數(shù)被調(diào)用(按 README 文件中的步驟生成完全的追蹤記錄):
清單 2. 解析出我們的 DLL 的路徑并檢查 DLL 是否存在
|
清單 3. 這一行展示我們的 DLL 所導(dǎo)出的函數(shù)
|
清單 4. 這里展示了 getTitle 被調(diào)用的位置
|
分析一個更大的應(yīng)用程序或多或少與此相似,不過您當(dāng)然會得到多得多的細(xì)節(jié),會遇到?jīng)]有被實(shí)現(xiàn)的函數(shù),等等。故障診斷通常大概是提供缺少的 DLL 和調(diào)整配置;偶爾,您將需要去實(shí)現(xiàn)或修復(fù)一個函數(shù)。
結(jié)束語
如果您正在尋找將現(xiàn)有的 Windows 應(yīng)用程序轉(zhuǎn)移到 Linux 的方法,開放源代碼的 Wine 和來自 CodeWeavers 的商用產(chǎn)品都是極好的選擇。應(yīng)用程序可以運(yùn)行于 Wine 之上,或者使用 Winelib 工具包進(jìn)行移植。
Wine 還為那些希望介入開放源代碼軟件的人們提供了一個獨(dú)一無二的機(jī)會。從特別困難的到適合初學(xué)者的,有大量的各種復(fù)雜程度的項(xiàng)目--而且 Wine 社區(qū)非常活躍并提供非常多的支持。
參考資料
下載本文中演示的 示例應(yīng)用程序。
自 Wine 下載頁獲得 Wine 的二進(jìn)制文件和源代碼,通過 Wine 的官方 Web 站點(diǎn) WineHQ 深入了解 Wine 及其歷史。
Wine 用戶指南將幫您起步。 Chapter 7. Troubleshooting / Reporting bugs 中包括很多指向有用信息資料的鏈接,比如 Frank's Corner for tips and tricks;可以到 Wine Google Group 尋求幫助,到 dll-files.com 尋找缺少的 DLL —— 還有更多。
依賴瀏覽器和追蹤工具將有力地幫助您讓 Windows 二進(jìn)制程序平滑到運(yùn)行于 Wine 之上。Microsoft Platform SDK 中包括depends.exe Dependency Walker;在 Sysinternals 可以找到類似的工具;同時 Epsilon Squared提供了一個非常好的 Windows 安裝追蹤工具。
DLL 不只會在 Wine 中引發(fā)問題;對 Windows 用戶來說它們也是著名的問題源頭。MSDN 文章 The End of DLL Hell解釋了原因。
Windows API 文檔的缺乏是美國政府對 Microsoft 的反拖拉斯訴訟的內(nèi)容。自由軟件基金會(Free Software Foundation)首席法律顧問 Eben Moglen 在 Free Software Matters: Shaking Up The Microsoft Settlement中討論了 API 和解決條款。
除了 Wine 用戶指南以外, WineHQ 文檔頁上還列出了其他很多有用的文章。
在 WineHQ 查找現(xiàn)在的和以前的 Wine Weekly News的話題。
Winelib 用戶指南涵蓋了使用 Winelib 將您的應(yīng)用程序移植到 Linux 和 Unix 所需要知道的所有內(nèi)容。
Wine 應(yīng)用程序數(shù)據(jù)庫列出了那些可以通過 Wine 運(yùn)行于 Linux 上的 Windows 應(yīng)用程序,并有很多它們的截圖。
Francois Gouget有很多 關(guān)于 Wine 的資料,包括如何做出貢獻(xiàn);為什么 Wine 重要;有趣的 Wine API 統(tǒng)計以及更多資料!
CodeWeavers 的 Crossover 產(chǎn)品基于 Wine。
WineX 也是構(gòu)建于 Wine 源代碼之上。WineX 的目標(biāo)是為 DirectX 實(shí)現(xiàn)一個 Linux 兼容層,因此其名字中包含字母 X。
Wine 不是一個仿真器 —— 但是有很多可用的仿真器可以讓您在 Linux 或 Unix 上運(yùn)行 Windows 二進(jìn)制程序。其中包括 VMWare 和 Win4Lin,這兩個都是私有的;還有開放源代碼的 Bochs 項(xiàng)目。使用這些程序,Windows 的一個拷貝可以運(yùn)行于仿真器之上,這個仿真器會確保 Windows OS 所需要的硬件條件都得到滿足。
用于交叉生成應(yīng)用程序的 Xmingwin( developerWorks, 2003 年)讓您只需要重新編譯就可以將 Linux 應(yīng)用程序移植到 Windows。
WebSphere Homepage Builder for Linux需要 Keio 大學(xué)定制的 Wine 版本。
在 developerWorks Linux 專區(qū)可以找到更多為 Linux 開發(fā)者準(zhǔn)備的參考資料。
在 Developer Bookstore 的 Linux 區(qū)可以找到大量 關(guān)于 Linux 的書籍。