運(yùn)行全攻略:從參數(shù)配置到崩潰排查)
很多人把 CrossOver 當(dāng)成一個(gè)“雙擊就能運(yùn)行 Windows 程序”的傻瓜工具真到某個(gè)程序跑不起來(lái)的時(shí)候才發(fā)現(xiàn)界面里連個(gè)能塞參數(shù)的地方都找不到。實(shí)際上CrossOver 的價(jià)值恰恰體現(xiàn)在“帶選項(xiàng)運(yùn)行”這個(gè)入口里調(diào) Windows 版本、塞環(huán)境變量、抓崩潰日志、看幀數(shù)全是靠這個(gè)不太起眼的窗口來(lái)完成的?!皫нx項(xiàng)運(yùn)行”說(shuō)穿了就是給一個(gè)待運(yùn)行的 Windows 程序附加更多啟動(dòng)參數(shù)和環(huán)境變量的通道。它不負(fù)責(zé)直接修復(fù)程序本身但它能告訴你“程序?yàn)槭裁雌鸩粊?lái)”“哪個(gè) DLL 加載失敗”“游戲吃多少幀”甚至能讓同一個(gè)程序在幾個(gè)不同的虛擬 Windows 環(huán)境里分別試跑避免動(dòng)到主環(huán)境。這篇文章我把平時(shí)排查的思路完整捋一遍從基礎(chǔ)概念、參數(shù)寫(xiě)法一直講到底層崩潰分析。無(wú)論你只是想在 Mac 上玩 Windows 游戲還是跑某個(gè)老舊的行業(yè)軟件這東西都值得花十分鐘掌握。1. 先搞清楚“帶選項(xiàng)運(yùn)行”和“一鍵運(yùn)行”差在哪1.1 一個(gè)容器Bottle相當(dāng)于一臺(tái)虛擬 WindowsCrossOver 里有個(gè)核心概念叫“容器”英文名 Bottle。你可以把它理解成一臺(tái)只有 C 盤(pán)、注冊(cè)表和一些系統(tǒng) DLL 的迷你 Windows。不同容器之間互相隔離裝在這個(gè)容器里的軟件不會(huì)污染另一個(gè)容器。每個(gè)容器可以單獨(dú)設(shè)定 Windows 版本比如 A 容器是 Windows 10B 容器是 Windows 7這比全局統(tǒng)一改版本要安全得多。而“帶選項(xiàng)運(yùn)行”的最大價(jià)值就是在不破壞這個(gè)容器默認(rèn)配置的前提下臨時(shí)指定某次運(yùn)行要用哪個(gè)容器、用哪個(gè) Windows 版本、帶哪些參數(shù)。也就是說(shuō)你不用為了測(cè)一個(gè)游戲去把容器的 Windows 版本從 10 改成 7只需在“帶選項(xiàng)運(yùn)行”界面里臨場(chǎng)選一次跑完這次主配置不動(dòng)。這個(gè)設(shè)計(jì)對(duì)反復(fù)驗(yàn)證特別重要。很多老程序改完 Windows 版本后要重啟容器甚至重裝軟件一旦配置改崩了整個(gè) Bottle 可能就廢了。帶選項(xiàng)運(yùn)行把“試錯(cuò)”的成本壓到最低我平時(shí)做兼容性測(cè)試基本不會(huì)直接改 Bottle 屬性全從這個(gè)入口進(jìn)。1.2 哪些場(chǎng)景最值得用帶選項(xiàng)運(yùn)行有人會(huì)問(wèn)既然容器配置可以隨時(shí)改為什么還要多此一舉我用下來(lái)的實(shí)際感受是至少有三類場(chǎng)景繞不開(kāi)它。第一類跑需要特定啟動(dòng)參數(shù)的程序。比如某些游戲要用-window-mode borderless進(jìn)無(wú)邊框窗口某些 Java 工具要設(shè)置-Xmx4g來(lái)擴(kuò)大堆內(nèi)存某些國(guó)產(chǎn)軟件要加--no-sandbox才能正常加載。這些參數(shù)在正常雙擊快捷方式時(shí)根本傳不進(jìn)去但在“帶選項(xiàng)運(yùn)行”里直接填進(jìn)“參數(shù)”字段就行。第二類懷疑兼容性配置被改壞時(shí)。程序原來(lái)能跑后來(lái)某個(gè)版本更新后就崩了你在界面上怎么排查都很痛苦。帶選項(xiàng)運(yùn)行可以讓你臨時(shí)切到輕量干凈的測(cè)試容器不帶任何額外環(huán)境變量跑一次看是不是歷史配置殘留導(dǎo)致的問(wèn)題。第三類抓崩潰現(xiàn)場(chǎng)。平常雙擊啟動(dòng)程序崩了以后圖形界面直接消失日志一閃而過(guò)你根本看不到原因。但用帶選項(xiàng)運(yùn)行時(shí)可以先打開(kāi)終端輸出把所有報(bào)錯(cuò)、斷點(diǎn)、異常信息如實(shí)打到日志里崩潰那一刻的上下文全都能留下來(lái)。換句話說(shuō)這個(gè)功能就像汽車的“檢修模式”平時(shí)你不用碰它但一旦出了疑難雜癥它就是唯一的正確入口。2. 調(diào)參數(shù)前先把這些關(guān)鍵設(shè)置吃透2.1 Windows 版本和容器的雙重關(guān)系跨平臺(tái)運(yùn)行 Windows 程序最常碰到的兼容性概念就是“Windows 版本”。程序安裝時(shí)會(huì)讀取注冊(cè)表里的版本號(hào)某些新版軟件看到版本號(hào)太低就直接拒絕運(yùn)行某些舊軟件看到版本號(hào)太高反而會(huì)因?yàn)?API 行為變化而崩潰。帶選項(xiàng)運(yùn)行里的 Windows 版本下拉框本質(zhì)是臨時(shí)給程序偽造一個(gè)“我正運(yùn)行在某個(gè) Windows 版本上”的環(huán)境。比如一個(gè)老游戲只對(duì) Windows 7 做了完整測(cè)試你在外面選了 Windows 10游戲安裝時(shí)可能會(huì)提示版本不兼容但用帶選項(xiàng)運(yùn)行強(qiáng)制設(shè)為 Windows 7它就可能正常啟動(dòng)。容器和 Windows 版本不是同一層?xùn)|西。一個(gè)容器是完整的虛擬磁盤(pán)環(huán)境可以裝很多軟件Windows 版本只是注冊(cè)表里的一組版本標(biāo)記和 API 行為開(kāi)關(guān)。我建議日常為不同用途建不同容器比如專門(mén)一個(gè)“游戲容器”設(shè)成 Windows 10一個(gè)“老軟件容器”設(shè)成 Windows 7再用帶選項(xiàng)運(yùn)行去做微調(diào)。永遠(yuǎn)不要在“主力容器”上反復(fù)橫跳版本否則 32 位注冊(cè)表項(xiàng)和 64 位注冊(cè)表項(xiàng)很容易錯(cuò)亂。2.2 環(huán)境變量和 DLL 覆蓋寫(xiě)法環(huán)境變量是 Wine 類項(xiàng)目里最重要的高級(jí)功能。帶選項(xiàng)運(yùn)行窗口通常會(huì)有“環(huán)境變量”一欄它的作用是在啟動(dòng)前預(yù)設(shè)一系列傳給 Wine 的配置項(xiàng)。最常用的是WINEDLLOVERRIDES用于控制 DLL 的加載順序。格式類似WINEDLLOVERRIDESd3d9b;d3d11b;dxgib這里等號(hào)后面的b代表 built-in也就是優(yōu)先使用 Wine 自帶的模擬 DLLn代表 native優(yōu)先使用軟件自帶的 DLL 文件。實(shí)際調(diào)試中如果某個(gè)游戲提示d3dx9_43.dll缺失可以下載官方 DirectX 運(yùn)行庫(kù)后把d3dx9_43n寫(xiě)進(jìn)去試試強(qiáng)制程序優(yōu)先加載那個(gè)剛裝好的 DLL。另一個(gè)常見(jiàn)變量是DXVK_HUD。在開(kāi)啟 DXVK 圖形后端后把DXVK_HUDfps填入環(huán)境變量游戲窗口左上角會(huì)直接顯示實(shí)時(shí)幀率。具體數(shù)值包括 FPS 和渲染幀時(shí)間適合快速判斷性能瓶頸。后面實(shí)測(cè)幀數(shù)時(shí)會(huì)專門(mén)用到。再比如WINEDEBUG它控制 Wine 的調(diào)試輸出。默認(rèn)值是-all也就是不輸出細(xì)節(jié)遇到崩潰時(shí)可以設(shè)置成WINEDEBUGseh,tid,loaddll加載 DLL 的順序、線程切換和異常處理過(guò)程會(huì)全部輸出到終端。雖然日志量會(huì)很大但對(duì)于抓“一啟動(dòng)就崩”的問(wèn)題特別有效。2.3 命令行參數(shù)和常見(jiàn)坑在“參數(shù)”字段里填的字符串會(huì)原封不動(dòng)傳給 Windows 程序這個(gè)跟終端里執(zhí)行命令是一樣的。常見(jiàn)坑是路徑里有空格卻不加引號(hào)。比如某工具放在C:\Program Files\Some App\run.exe如果直接寫(xiě)--config C:\Program Files\Some App\config.ini會(huì)被程序拆成兩個(gè)參數(shù)。正確寫(xiě)法是給路徑加英文雙引號(hào)--config C:\Program Files\Some App\config.ini另一個(gè)坑是反斜杠轉(zhuǎn)義??缙脚_(tái)環(huán)境下Windows 路徑的反斜杠在某些終端里會(huì)被當(dāng)作轉(zhuǎn)義符。帶選項(xiàng)運(yùn)行界面一般不會(huì)先做 shell 解析所以你可以直接寫(xiě) Windows 風(fēng)格路徑但千萬(wàn)不能在前后綴混用中文引號(hào)。參數(shù)調(diào)錯(cuò)時(shí)程序不一定崩潰可能只是靜默忽略。如果你不確定某個(gè)參數(shù)是否生效最好的驗(yàn)證辦法是分兩步先加一個(gè)程序一定會(huì)識(shí)別的參數(shù)比如--version或--help確認(rèn)參數(shù)傳遞通道通暢再換正式參數(shù)。2.4 圖形相關(guān)的隱藏選項(xiàng)帶選項(xiàng)運(yùn)行里最容易被忽略的一類參數(shù)是圖形后端選項(xiàng)。CrossOver 在底層依然依賴 Wine而 Wine 有兩種主流的 3D 圖形翻譯路線一種是把 Direct3D 調(diào)用轉(zhuǎn)到 Vulkan再由系統(tǒng)顯卡驅(qū)動(dòng)處理另一種是直接轉(zhuǎn)到本機(jī) Metal 或 OpenGL。通常較新的游戲會(huì)默認(rèn)走比較成熟的 D3D Metal 或 DXVK 后端性能接近原生。但有些舊游戲反而在默認(rèn)后端下會(huì)花屏、閃退這時(shí)就需要在帶選項(xiàng)運(yùn)行里強(qiáng)制切換后端比如只啟用某個(gè) DLL 對(duì)應(yīng)的轉(zhuǎn)換層。如果你不確定當(dāng)前跑的是哪個(gè)后端可以臨時(shí)填環(huán)境變量開(kāi)啟 HUD例如DXVK_HUDdevinfo,fps游戲啟動(dòng)后如果看到一長(zhǎng)串顯卡和驅(qū)動(dòng)信息并伴隨實(shí)時(shí) FPS說(shuō)明確實(shí)走的是 DXVK如果沒(méi)有任何 HUD但幀數(shù)穩(wěn)定那說(shuō)明還在默認(rèn)的轉(zhuǎn)換路徑上。3. 想看幀數(shù)和性能數(shù)字先學(xué)會(huì)“看 HUD 和寫(xiě)日志”3.1 不要在 Mac 側(cè)用全局錄屏測(cè)幀數(shù)的大坑很多人在 Mac 上跑 Windows 游戲第一反應(yīng)是打開(kāi) macOS 自帶的“屏幕錄制”或第三方錄屏軟件來(lái)看幀率。這個(gè)做法誤差極大因?yàn)槠聊讳浿票旧頃?huì)占用 Metal 編碼器資源而且 macOS 側(cè)捕獲到的是合成后的桌面幀率不是 Windows 游戲內(nèi)部的渲染幀率。更合適的思路是讓游戲自己報(bào)告幀數(shù)。游戲內(nèi)通常自帶FPS 計(jì)數(shù)器在設(shè)置菜單里打開(kāi)即可。如果游戲內(nèi)部沒(méi)有這個(gè)功能再考慮在帶選項(xiàng)運(yùn)行環(huán)境變量里塞DXVK_HUDfps讓 Wine 渲染層在左上角畫(huà)出一個(gè)性能浮層。這個(gè)浮層還有一個(gè)好處它能區(qū)分draw call數(shù)量和實(shí)際渲染幀率。比如幀率卡在 30 FPS但GPU占用只有 40%說(shuō)明瓶頸往往不在顯卡而在 CPU 翻譯 Direct3D 調(diào)用或驅(qū)動(dòng)同步等待上。3.2 如何把幀數(shù)數(shù)據(jù)寫(xiě)成穩(wěn)定可復(fù)現(xiàn)的日志光看浮層數(shù)字還不夠做性能對(duì)比時(shí)需要一組可復(fù)現(xiàn)的數(shù)據(jù)。帶選項(xiàng)運(yùn)行模式可以配合啟動(dòng)參數(shù)把統(tǒng)計(jì)結(jié)果落盤(pán)。很多游戲支持-benchmark或-log參數(shù)比如某些引擎日志里會(huì)直接寫(xiě)一行平均幀率和 1% Low 幀率。如果游戲不支持可以通過(guò)DXVK_HUD0,fps的變體配合抓取控制臺(tái)輸出來(lái)處理。這部分在不同 CrossOver 版本窗口里的入口位置略有差異但思路是統(tǒng)一的先把 HUD 打開(kāi)確認(rèn)有數(shù)字輸出后再切換到崩潰排查用的終端把幾十秒內(nèi)的幀率變化連同 GPU 占用一起存成一個(gè)文件。做記錄時(shí)我會(huì)固定一個(gè)“標(biāo)準(zhǔn)跑圖路徑”比如進(jìn)入游戲后選同一關(guān)卡、同角度、奔跑 30 秒盡量不讓場(chǎng)景光照和 NPC 數(shù)量變化干擾數(shù)據(jù)。這樣改一個(gè)參數(shù)前后的對(duì)比才有說(shuō)服力。3.3 從 30 幀提到 60 幀的優(yōu)先調(diào)整順序當(dāng)你測(cè)得幀數(shù)偏軟時(shí)能調(diào)整的方向很多但優(yōu)先級(jí)不一樣。我最常做的順序如下先看 Windows 版本是否正確。若一個(gè)游戲是被翻譯層當(dāng)作 Windows 8/10 運(yùn)行但游戲本身主程序是為 Windows 7 編譯的某些 API 會(huì)走慢速兼容路徑。把版本切到程序推薦的版本有時(shí)能憑空漲 10% 幀數(shù)。再查同步選項(xiàng)。CrossOver 里的 Esync 和 Msync 這類同步原語(yǔ)可以大幅降低多線程游戲在跨平臺(tái)層的等待時(shí)間。開(kāi)啟后如果幀數(shù)提升明顯說(shuō)明瓶頸在線程同步等待。最后檢查 GPU 內(nèi)存上限。帶選項(xiàng)運(yùn)行有時(shí)能設(shè)置一個(gè)顯存閾值這個(gè)閾值太低時(shí)新紋理不斷在內(nèi)存里擠占可能導(dǎo)致頻率掉一半。把它提高到 4096 MB 或更高對(duì)現(xiàn)代游戲有正面影響。注意不要一開(kāi)始就盲目調(diào)高圖形質(zhì)量兼容層里真正影響幀數(shù)的常常不是渲染分辨率而是同步機(jī)制和內(nèi)存映射方式。把這幾項(xiàng)全試過(guò)一遍再改畫(huà)質(zhì)會(huì)省很多時(shí)間。3.4 畫(huà)質(zhì)參數(shù)會(huì)掩蓋兼容性問(wèn)題的信號(hào)在跨平臺(tái)層里畫(huà)質(zhì)參數(shù)和工作原理很值得關(guān)注。打開(kāi) DX11 下的高質(zhì)量陰影游戲會(huì)不會(huì)閃退往往不是顯卡性能問(wèn)題而是某些 Shader 在不熟悉的驅(qū)動(dòng)翻譯路徑上出了岔子。如果你遇到“某個(gè)特定特效一打開(kāi)就崩”的情況不要先怪顯卡先在帶選項(xiàng)運(yùn)行里把渲染后端從默認(rèn)切到 Vulkan 或干脆強(qiáng)制軟件渲染逐級(jí)替換來(lái)判斷是否 Shader 編譯觸發(fā)的 Bug。實(shí)際排查中把“所有畫(huà)質(zhì)都調(diào)低后再試一次”作為控制組非常管用。如果低畫(huà)質(zhì)下穩(wěn)定 60高畫(huà)質(zhì)下秒崩那就不是兼容層跑不動(dòng)而是圖形翻譯對(duì)某個(gè)高級(jí)特性支持不到位。把崩潰時(shí)的日志截下來(lái)再?zèng)Q定是等更新還是繞開(kāi)這個(gè)特效。4. 從崩潰到日志真正入門(mén)排查4.1 崩潰日志應(yīng)該去哪里看跨平臺(tái)運(yùn)行 Windows 程序的崩潰通常會(huì)以 Windows 程序自身的“已停止工作”彈窗形式出現(xiàn)但這個(gè)彈窗拿不到任何可讀的堆棧信息。要拿到有效數(shù)據(jù)先要在“帶選項(xiàng)運(yùn)行”界面里把調(diào)試輸出打開(kāi)讓終端進(jìn)程能接收到 Wine 底層打印出的信息。日志入口根據(jù) CrossOver 版本不同會(huì)顯示為“顯示終端”“打開(kāi)控制臺(tái)”之類的按鈕本質(zhì)上是在前臺(tái)拉起一個(gè)標(biāo)準(zhǔn)輸出流。點(diǎn)擊前建議先把WINEDEBUG設(shè)置好只關(guān)注最關(guān)鍵的模塊不要用默認(rèn)的-all不然所有可用的信息都被過(guò)濾掉了。另外崩潰時(shí)的 Windows 事件日志在~/.cxoffice對(duì)應(yīng) Bottle 目錄下也能找到一部分。如果程序崩潰后留下.dmp文件把.dmp保存好它是后續(xù)分析里最接近真實(shí)堆棧的資料比一大堆 DLL 日志都值錢(qián)。4.2 最常見(jiàn)的三種崩潰和對(duì)應(yīng)解法我遇到過(guò)很多次的崩潰類型其實(shí)高度集中。列成一張速查表更直白崩潰現(xiàn)象常見(jiàn)原因首選處理方向啟動(dòng)時(shí)提示缺少 DLL 或某種運(yùn)行庫(kù)VC Runtime 或.NET 運(yùn)行庫(kù)缺失在該 Bottle 里安裝對(duì)應(yīng)運(yùn)行庫(kù)再用WINEDLLOVERRIDES指定加載順序進(jìn)主菜單正常一開(kāi)戰(zhàn)斗就崩圖形翻譯層對(duì)特定 Shader 支持不全切換圖形后端更新 DXVK 對(duì)應(yīng)組件關(guān)閉特定畫(huà)質(zhì)特效啟動(dòng)后一直白屏點(diǎn)哪里都沒(méi)反應(yīng)Windows 版本與程序要求不一致臨場(chǎng)切到較低版本試跑確認(rèn)后再改 Bottle 屬性程序能打開(kāi)但一操作文件就崩工作目錄或數(shù)據(jù)路徑錯(cuò)誤在帶選項(xiàng)運(yùn)行里把工作目錄改為安裝所在磁盤(pán)不要用默認(rèn)系統(tǒng)路徑這個(gè)表只解決 70% 問(wèn)題但已經(jīng)有了基本的排查路徑。剩下 30% 需要你結(jié)合崩潰日志分析棧幀。4.3 崩潰日志里最值得盯住的三個(gè)關(guān)鍵詞日志滿天飛時(shí)別從頭到尾亂讀。我通常只搜索三處關(guān)鍵信息fixme、err、trace。err開(kāi)頭的行往往表示某個(gè) API 調(diào)用真正失敗了比如找不到模塊、無(wú)法創(chuàng)建表面、內(nèi)存分配失敗。fixme表示 Wine 遇到了一個(gè)尚未完整實(shí)現(xiàn)的功能程序可能繼續(xù)運(yùn)行也可能在下一秒崩潰。trace里的內(nèi)容則能看見(jiàn)程序從啟動(dòng)到崩潰之間大概執(zhí)行了哪些關(guān)鍵調(diào)用路徑。一個(gè)典型流程是啟動(dòng)游戲后日志先出現(xiàn)大量fixme:d3d11開(kāi)頭的提示說(shuō)明 D3D11 部分要走兼容路徑然后突然蹦出err:seh后面跟著一串帶括號(hào)的地址這個(gè)seh是結(jié)構(gòu)化異常處理那一行基本上就是崩潰前的最后一次狀態(tài)。遇到err:seh不要試圖從完整堆棧里反推太多把它前后三行一起復(fù)制下來(lái)去搜索比對(duì)著幾個(gè)十六進(jìn)制地址猜要靠譜得多。4.4 用最小復(fù)現(xiàn)法鎖死崩潰原因崩潰調(diào)試?yán)镒钊菀追傅腻e(cuò)是一次改太多東西。同一個(gè)游戲既切了 Windows 版本又加了 DLL 覆蓋還換了圖形后端如果它還是崩潰你根本不知道是哪一步起了反作用。正確做法是構(gòu)造最小復(fù)現(xiàn)環(huán)境。先用一個(gè)全新的容器什么運(yùn)行庫(kù)都不裝通過(guò)“帶選項(xiàng)運(yùn)行”直接加載游戲主程序觀察最基礎(chǔ)的啟動(dòng)路徑是否崩潰。如果不崩潰再逐步進(jìn)入正式場(chǎng)景每加一個(gè)變量跑一次短的日志。比如懷疑是 VC 運(yùn)行庫(kù)缺失導(dǎo)致的啟動(dòng)崩潰就先在舊 Bottle 里運(yùn)行帶選項(xiàng)命令觀察錯(cuò)誤碼是否都指向某個(gè) DLL然后去新容器安裝運(yùn)行庫(kù)用同樣的帶選項(xiàng)命令再跑一次。結(jié)果一致就能鎖定原因結(jié)果不一致說(shuō)明原來(lái)的 Bottle 里還有別的污染斷舍離比搶救快得多。5. 實(shí)際戰(zhàn)例一次“打開(kāi)直接閃退”的完整排查流程5.1 開(kāi)始前的三樣準(zhǔn)備紙上談兵再多不如親手走一遍。下面我給出一個(gè)比較典型的故障樣例某個(gè) Windows 版小眾工具在 Mac 上雙擊運(yùn)行后界面出現(xiàn)一兩秒就消失沒(méi)有任何報(bào)錯(cuò)彈窗。按照經(jīng)驗(yàn)這種問(wèn)題多半出在啟動(dòng)參數(shù)或容器環(huán)境上而那些已經(jīng)裝好的運(yùn)行庫(kù)反而可能不背鍋。開(kāi)始前需要準(zhǔn)備三樣?xùn)|西一個(gè)干凈的測(cè)試容器不要裝額外運(yùn)行庫(kù)保證環(huán)境可復(fù)現(xiàn)一個(gè)可寫(xiě)日志的終端入口把 CrossOver 運(yùn)行程序的輸出保存下來(lái)一份備份的原始程序的啟動(dòng)命令和常見(jiàn)運(yùn)行目錄避免待會(huì)把目標(biāo)路徑搞錯(cuò)。準(zhǔn)備不齊就別開(kāi)始。尤其日志輸出沒(méi)打開(kāi)就運(yùn)行程序很多閃退信息轉(zhuǎn)瞬即逝再想復(fù)現(xiàn)又得重來(lái)。5.2 從“每次閃退”到“抓到一個(gè)錯(cuò)誤”第一步在“帶選項(xiàng)運(yùn)行”里選擇那個(gè)可執(zhí)行程序環(huán)境變量先都留空工作目錄設(shè)成程序安裝盤(pán)的根目錄。點(diǎn)擊運(yùn)行后觀察閃退是否復(fù)現(xiàn)。務(wù)必先復(fù)現(xiàn)不能復(fù)現(xiàn)的問(wèn)題等于不存在。啟動(dòng)后閃退復(fù)現(xiàn)我立刻在終端輸出里看到了一條以前從沒(méi)見(jiàn)過(guò)的err:module信息指向一個(gè)msvcr120.dll文件加載失敗。這說(shuō)明程序需要 Visual C 2013 運(yùn)行庫(kù)而該 Bottle 沒(méi)有安裝。這就是雙擊快捷方式看不到信息、但帶選項(xiàng)運(yùn)行能捕獲到的原因。第二步進(jìn)入該 Bottle安裝對(duì)應(yīng)的 vcrun2013 支持包然后再用帶選項(xiàng)運(yùn)行啟動(dòng)同一程序。此時(shí)程序不再閃退主界面出現(xiàn)。第三步我在帶選項(xiàng)運(yùn)行里增加WINEDLLOVERRIDESmsvcr120n來(lái)繞過(guò)內(nèi)置的 DLL測(cè)試它有沒(méi)有依賴其它缺失的組件。穩(wěn)定運(yùn)行后再把這些設(shè)置固化到容器配置或快捷方式中否則以后每次都要手動(dòng)帶參數(shù)啟動(dòng)。5.3 為什么每次排查都要把“參數(shù)殘留”清干凈做完上面那三步后我發(fā)現(xiàn)一個(gè)很容易被忽略的問(wèn)題如果之前為了規(guī)避另一個(gè) Bug曾經(jīng)在某次帶選項(xiàng)運(yùn)行中加入過(guò)一些臨時(shí)環(huán)境變量比如讓 Wine 忽略某個(gè) DLL 或切換成軟件渲染那這次正常啟動(dòng)后這些陳舊設(shè)置在日志里還會(huì)繼續(xù)生效??缙脚_(tái)層對(duì)已有環(huán)境變量非常敏感經(jīng)常是“上一次為了修 A 加的變量過(guò)幾周開(kāi)始阻撓 B”。所以每次做完一種驗(yàn)證都建議馬上把帶選項(xiàng)運(yùn)行里的字段恢復(fù)默認(rèn)再跑一次確認(rèn)環(huán)境是干凈的。這在實(shí)際項(xiàng)目中比任何單一技巧都更能救你。說(shuō)回這次的案例安裝 vcrun2013 之后問(wèn)題就解決了??雌饋?lái)像是“缺組件”的簡(jiǎn)單錯(cuò)誤真正困難的不是安裝而是從閃退這種模糊信號(hào)里定位到msvcr120這個(gè)具體文件。如果不借助帶選項(xiàng)運(yùn)行把日志完整輸出問(wèn)題可能得猜很久。我的個(gè)人習(xí)慣是給每個(gè)需要長(zhǎng)期維護(hù)的 Windows 程序都建一份“標(biāo)準(zhǔn)啟動(dòng)卡片”記錄它用哪個(gè)容器、哪些環(huán)境變量、工作目錄設(shè)在哪個(gè)路徑、上次崩潰修復(fù)時(shí)改過(guò)什么。CrossOver 里很多“時(shí)好時(shí)壞”的問(wèn)題翻記錄比對(duì)之后都能找到原因。這個(gè)方法建議你也用起來(lái)。