2013-02-28 66 views
3

Shell命名空間擴展非常複雜。過去10年來,我們一直在構建shell命名空間擴展;其最新版本是MagicRAR中的檔案文件夾功能(www.magicrar.com)。Delphi中使用VCL的Shell命名空間擴展

不幸的是,儘管非常仔細的編碼,確保線程能夠正確訪問共享內存等,但我們的shell命名空間擴展仍然偶爾發生崩潰。 Explorer主機進程在使用我們的shell命名空間擴展期間或之外崩潰。

我們使用了各種工具,例如AQTime Pro來排除我們的shell命名空間擴展代碼。沒有內存覆蓋或其他類似的訪問問題報告。這隻剩下一個罪魁禍首:VCL不是線程安全的!

確實,我們使用VCL作爲shell命名空間擴展的一部分;資源管理器中的文件列表實際上是一個託管控件,在我們自己的shell命名空間擴展的情況下,它實際上是一個VCL窗口。我們現在甚至想知道(在多代開發之後)這是否是首先允許的場景...

主要應用程序對象甚至不存在於我們的shell命名空間擴展DLL中。使用TThread.Synchronize死鎖資源管理器,因爲主要的VCL線程還沒有創建任何地方。我們是否需要手動創建主VCL線程(如何?) - 可能在另一個DLL中 - 並通過該DLL重新路由所有UI創建/更新/銷燬?請記住,資源管理器可能會顯示包含我們的VCL窗口的任意數量的窗口。基於目標系統的配置,Explorer也可能作爲多個獨立進程運行,或作爲單個進程運行。

我們在John Lam的出發點(就像大多數Delphi shell命名空間開發人員所知道的那樣)基於shell命名空間擴展。當然,正如你在最終產品中看到的那樣,對這個起點進行了重大修改。 John Lam從來沒有在他的幻燈片和示例項目中討論過VCL是否是線程不安全的問題。

我們也試圖在過去的十年中使用多個版本的ShellPlus組件。他們已經完成了一些出色的工作,但不幸的是,根據我們的經驗,即使是基於代碼的非常基礎的努力,也提供了比我們自己的代碼更糟糕的結果。

ShellPlus實際上還提供了使用Explorer自己的預定義主機窗口的功能,而不是創建自定義的VCL窗口;雖然這可能會迴避任何VCL線程問題,但根據我們的經驗,這還不是一個可行的解決方案 - 因爲ShellPlus shell命名空間擴展一直不如我們的家庭釀造代碼穩定,無論是否加入VCL。

所以首先,這個問題是理論上的問題 - VCL是否可以用在使用Explorer內部的VCL窗口作爲進程主機的shell命名空間擴展中?

如果是這樣,在這種情況下如何處理VCL線程安全問題?

+1

您是否真的檢查過觸摸GUI的代碼是否在每個進程的多個線程中運行? Win32有它自己的線程規則。具體而言,窗口具有線程關聯。我期望任何時候瀏覽器都希望你使用窗口句柄,你總是會在同一個線程中調用。換句話說,我質疑線程關聯是否實際上是您的問題。 – 2013-02-28 10:15:48

+0

如果資源管理器非常關注線程關聯性,那麼這很好,但是當多個資源管理器窗口顯示其中的多個VCL窗口副本時會發生什麼? VCL不是線程安全的,因此在同一進程內部仍然會有多個線程在執行GUI工作 - 而不是單個線程處理所有GUI工作。確實,Explorer創建了多個調用shell命名空間擴展的線程。 – user2118012 2013-02-28 12:17:40

+0

好的,在這一點上,你被洗淨了。 – 2013-02-28 13:24:15

回答

0

我們終於能夠解決這個問題。 固定shell命名空間擴展將在即將推出的MagicRAR 9.0中提供。 問題確實與VCL有關 - 否則我們的代碼非常好。 對於其他嘗試使用Delphi構建shell命名空間擴展的人:

是的,您可以使用Delphi構建shell命名空間擴展。但是,如果你使用的是VCL,你會遇到無數的隨機崩潰和不穩定。 而且 - 如果您不使用VCL,則使用Delphi幾乎沒有意義。好消息是你不需要修補VCL源代碼。只需使用專用的VCL線程。

4

該VCL確實不是線程安全的。在VCL應用程序之外運行並不能解除該規則。缺乏一個主要的VCL線程只會使情況變得更糟; VCL控件希望在主線程的上下文中運行,並且不存在這樣的線程,一般情況下也不可能。您正在使用的控件訪問各種全局變量而沒有任何同步保護,並且您無法修補任何VCL控件使用的所有單元。

使用常規的Windows API技術而不是VCL函數來創建和操作Explorer中的窗口。


您可以通過確保一些解決您的同步掛起檢查隊列告知何時,但沒有一個「主」線程,目前還不清楚是什麼你會與進行同步無論如何,所以Synchronize只是可能不成爲這項工作的正確工具。

+0

我想知道嘗試創建一個「主」VCL線程是否有意義,它將擁有所有GUI工作,處理所有同步,併成爲所有Synchronize()請求的目標。 – user2118012 2013-02-28 12:19:49

+0

請注意,如果無法使用VCL來管理shell命名空間擴展的GUI部分,它將無法爲項目使用Delphi。如果這是不可能做到的,那麼從另外一個可能是線程安全的語言重新編譯項目可能更有意義。 – user2118012 2013-02-28 12:21:18

+0

@user討論「線程安全語言」通常沒有意義。 「線程安全」本身是沒有意義的。你必須明確指出你所說的線程安全的具體形式。你仍然會發現你的擴展在Delphi中比在另一個C++中更容易編寫。 – 2013-02-28 20:23:01

相關問題