MFC程式和Windows PE 2.0的相容性問題

之前同事遇到一個問題,本來在各版本(2K/XP/Vista 32&64bit, and XP PE)上跑得好好的應用程式,到了Windows PE 2.0(based on Vista)上,按下enter就直接跳回提示符號,什麼錯誤訊息都沒有。

這問題Assign到我身上,由於這並不是我的project,對MFC程式不熟,更別提PE,摸不清楚頭緒的情形下,花了一整個星期的時間才找到問題所在。

一開始先花一天porting到VS 2005環境,結果是徒勞無功,後來在PE 2.0上用windbg trace,發現是DLL not found的問題,只是因為PE 2.0可能缺某些元件,所以不會跳出錯誤訊息。如此一來也就不容易曉得是什麼dll找不到。

由於對Windows Loader/dependency這方面並不了解,就猜想是程式用到的dll/library有問題,然後一個一個拔掉,拔光了發現沒作用,後來才曉得可以使用Visual Studio中的dumpbin /dependents來觀看一個程式需要哪些dll library,再比對PE 2.0中有哪些檔案,終於抓到是缺oledlg.dll這個dll。

但是程式本身並沒有用到oledlg.lib,於是用了一些方法找到,是MFC會去使用它(dynamic link MFC的話不會有問題,但是要求是一定要static link)。

當場就想說頭大了,如果是MFC要用到的,我該怎麼解決?oledlg.lib是default library,而且除了PE 2.0之外所有版本Windows都有內含,說不定根本無法除掉它的dependency。(而且對我們IHV而言,是不能要求客戶去改他們的PE Image,也不能在程式中亂附Microsoft的元件。)

不過測試過我自己寫的其它小程式,卻又可以執行,所以可能是MFC裡面某個特定功能才會導致。

後來就開了MFC source想要直接看使用oledlg的那點,但是程式執行時並不會hit breakpoint那一點。

無奈之下只好花時間把程式一塊一塊慢慢砍掉,砍到最後剩一點點皮,才發現原來是ActiveX control的關係。實際上程式本身並沒有用到ActiveX,但是因為Wizard預設會去init它,所以就還是會link到。

結論而言就是把AfxEnableControlContainer();砍掉即可,就這麼簡單一行,但是不懂就很難找。而且還好只有這一個地方用到,要是有好幾個地方用到,就得整個程序重來好幾遍了...orz。

這應該是滿容易遇到的問題,但是可能懂的人覺得簡單就都沒人記吧,都搜尋不到,這邊記下來說不定之後就幫到人了...

留言

張貼留言

這個網誌中的熱門文章

文言文

談談台灣人使用統傳漢字的優越心態

台灣工程師常唸錯的英文單字