2010-03-17 54 views
1

很久以前,我發現由於使用了Delphi打開文件和/或保存文件對話框(它封裝了Windows對話框),我在代碼中訪問衝突。我在幾個論壇上提出了一些問題,並被告知可能是由於某些程序向shell系統添加鉤子導致每個進程注入DLL的方式,其中一些可能會導致程序混亂。爲了記錄,我使用的編程環境是在Windows XP 32位上運行的Delphi 6 Professional。當使用Windows文件對話框時,在奇怪位置訪問衝突

當時我沒有使用Delphi的Dialog組件,而是直接調用comdlg32.dll。這很好地解決了這個問題。

今天我第一次使用內存映射文件,當然,訪問衝突開始出現在代碼的怪異部分。我嘗試了我的comdlg32.dll直接調用,這次它沒有幫助。爲了將問題隔離爲測試,我創建了一個列表框,其中包含我在測試期間使用的完全相同的文件。這些是我從「打開文件」對話框中選擇的完全相同的測試文件,然後使用啓動我的內存映射文件。我設置了一些東西,通過單擊列表框中的文件,我將在我的內存映射文件測試中使用該文件,而不是調用comdlg32.dll對話框函數來選擇測試文件。

同樣,訪問violatons消失。爲了向您展示它是如何引人注目的解決方案,我從1到3次試用中遇到了訪問衝突,而沒有任何衝突。不幸的是,當然當我需要使用文件對話框時,它會咬我。

有沒有其他人處理過這個問題,並發現真正的罪魁禍首?你們有沒有找到我可以用來解決這個問題的解決方案,而不是像我現在一樣圍繞它跳舞?

在此先感謝。

+0

你需要得到在碰撞發生堆棧。使用NTSD並設置公共符號。 http://msdn.microsoft.com/en-us/library/cc266473.aspx – 2010-03-17 22:15:17

+0

我從來沒有見過這個問題,但有一點,如果你對Delphi 6的可能(或許)幫助與更換內存管理器FastMM4,比舊版本更穩定。 – 2010-03-17 22:24:21

+0

你好梅森。我正在使用FastMM4,我對每個詳細檢查都進行了幾次測試,特別是檢查堆損壞情況。它沒有找到任何東西。在我的程序中移動內存指令期間發生崩潰,就像很久以前一樣。這是因爲如果某些DLL寫了我的記憶中或可變控制存儲器移動的範圍的塊,但並沒有做到這一點的方式,錯位任何FastMM4的內存塊頭。但這是我的猜測,因爲我不知道根本原因。 – 2010-03-17 23:05:42

回答

5

我不明白如何使用Delphi對話框組件避免shell擴展DLL在您的程序中造成混亂,如果您直接調用COMDLG32.DLL。您仍在使用常用對話框,並且這些外殼擴展仍在注入中。

更有可能的是,不使用組件會在代碼中產生副作用,混淆或掩蓋底層問題,將其減輕到它似乎已解決的程度。

我懷疑這裏也是這種情況。

我不知道你的系統上安裝了什麼樣的hokey shell擴展 - 也許你有一些奇怪的擴展引發了一些問題。我所能說的是,在用Delphi編程的15年奇蹟Win32編程中我有從來沒有已知甚至聽說過Delphi通用文件對話框組件負責這樣的行爲。

一個簡單的方法來測試這當然是採取編譯的EXE,展現您的機器上的訪問衝突,並在一些其他「潔淨室」XP機器上運行相同的EXE,即沒有第三方外殼什麼時候安裝了擴展。

如果AV消失,那麼您可以更加確信問題與外殼擴展相關。然後,通過將已知外殼擴展一個接一個安裝到測試機器上,直到AV重新出現,您可以隔離罪魁禍首並決定如何處理它......如果這是您的用戶/客戶不太可能成爲的原因那麼您可以選擇將其列爲已知的兼容性問題,然後轉入其他問題。

如果AV的不但是消失,那麼你幾乎可以排除德爾福對話框或任何外殼擴展爲某種方式引起的。

更一般地,這將是最有益的,看看其中AV發生的代碼,如果在所有可能的。

附錄:

我沒有找到this reference to AV's occuring with the Common Dialog components themselves。這雖然不會被視爲一個AV的「奇怪的地方」,它始終可以在對話組件本身內重複使用。但我想我會提到它。如果不知道你的AV發生的確切位置,這可能與此有關。

+0

我很擔心這個問題,但還有一些細節。我最近將整個安裝程序移至新的Windows XP安裝的新計算機系統。另外,我爲測試內存映射文件代碼所做的項目只是一個簡單的項目,只包括我的「常規例程」文件中的幾個。普通香草主窗體上的所有組件都是Delphi VCL庫(列表框,按鈕等)。無可否認,我的組件調色板與第三方項目(包括JCL和JVCL)緊密相連,但我不認爲來自未使用組件的代碼會被編譯到項目中。 – 2010-03-18 02:19:06

+1

這取決於...如果這些第三方單位爲你的應用列表,包含初始化部分,那麼你會發現你拖動的東西,你也許不期待。但是,確切地看到這些AV發生的位置/時間(即源代碼)會是最有幫助的。否則,任何援助只能來自「心理調試」(閱讀:猜測/猜測)。 – Deltics 2010-03-18 02:33:03

+0

當我嘗試將數據從內存映射文件數據緩衝區複製到變量時,我在當前項目中的錯誤發生在Move()調用期間。它發生在移動指令複製字節的「重複移動字節」循環中(由於它是彙編程序代碼,所以在CPU窗口中執行指針)。當我不進行任何文件對話調用時,錯誤消失。我將在事件查看器中檢查第三方組件的初始化部分和DLL列表。 – 2010-03-18 12:38:27