軟體總存在這樣或者那樣的bug。
雖然測試員已經在很努力的尋找問題,程式員也在汗流浹背的除蟲,但是總會有一些情況被遺漏或者不可預測,比如使用者的硬體環境、網路狀況、作業系統差異等等,不一而足。而導致的結果則是彈出下面這樣一個讓使用者摸不著頭腦又惱火的提示,然後崩潰掉,令程式員尷尬不已。
而在一些成熟的軟體產品中,程式崩潰時我們看到的卻是另外一番畫面,比如QQ:
又比如迅雷:
你也想讓你的程式擁有友好的崩潰介面,降低使用者生氣的能量,並且收集一些必要的資訊進行調試,來完善你的程式嗎?如果你是MFC程式猿,請繼續圍觀,其他猿類請自行無視,並尋找適合你的猿糞。
其實MFC架構已經為我們考慮到這個問題,只是預設產生的應用程式架構沒有包含進去而已。實現這個功能的核心是函數:SetUnhandledExceptionFilter,想要瞭解這個函數的同學請查閱MSDN,這裡就不再贅述他的用法。本著複用主意的精神,本文介紹的內容來自於大家所熟悉的電驢(emule)的原始碼,電驢實現了上面那樣的功能,我只是把代碼從電驢裡拿出來加到自己的程式裡然後到這裡分享給你。
毫無疑問,電驢是一款優秀的軟體,並且在它華麗的外表下還有一副強壯的身體。它的代碼有非常優秀。它是基於MFC開發的開來源程式,需要原始碼的同學請猛擊這裡下載。
上面這幅圖就是電驢的原始碼包,我們要用到的就是那個被我選中的“CrashReporter”,它是一個獨立的工程,我們只需要根據需要做一些修改然後直接編譯即可。
另外我們還需要位於src\WorkLayer\目錄下的mdump.h和mdump.cpp,把這兩個檔案拷貝並加到你的工程裡,然後把mdump.cpp裡的下面這行去掉:
#include "CheckConflict.h" //ADDED by fengwen on 2006/12/25 : 檢測已知的第三方軟體衝突。
這個是用於檢測已知的會和電驢衝突的軟體,不再本文討論之列,有興趣的同學請自行研究。另外把TopLevelFilter函數裡的下面幾行也刪掉:
try
{
//ADDED by fengwen on 2006/12/25 <begin> : 檢測第三方軟體衝突。
CCheckConflict cc;
if (cc.CheckConflict(pExceptionInfo))
{
ExitProcess(1);
}
//ADDED by fengwen on 2006/12/25 <end> : 檢測第三方軟體衝突。
}
catch(...)
{
}
最後一步,在主程式架構類裡添加:
#include "mdump.h"
再到InitInstance函數裡添加下面的代碼:
theCrashDumper.Enable(_T("YourApp 1.0"), false);
好了,大功告成,現在編譯你的程式,在合適的地方增加測試代碼就可以實驗效果了。比如下面這兩行代碼會讓你的程式立即崩潰:
int n = 0;
int m = 10/n;
怎麼樣,效果還不錯吧?這個程式除了攔截進程異常,還能夠將異常的相關資訊組建檔案,然後上傳到你指定的伺服器,供你分析調試。當然你需要修改CrashReporter工程HttpUploadFileProc.cpp檔案HttpUploadFile函數裡相關變數的值,否則就上傳到到電驢的伺服器了。另外你還需要在你伺服器的WEB server上提供一個接收檔案上傳的程式,用來儲存使用者上傳的錯誤檔案。
最後再修改一下CrashReporter工程CrashReporter.cpp檔案InitInstance函數裡的下面這行代碼:
ShellExecute(NULL, "open", "eMule.exe", NULL, NULL, SW_SHOW);
把eMule.exe改為你程式的檔案名稱,要不然使用者的程式崩潰後在螢幕上看到的是一隻可愛的驢子,大概整個人也要被你搞崩潰了……
轉載請註明:來自美味兒blog
本文地址:http://blog.meiweier.com/2010/03/19/mfc-application-crash.html