Shell命名空间扩展非常复杂。在过去的十年中,我们一直在构建一个shell命名空间扩展;最新版本是MagicRAR的Archive Folders功能(www.magicrar.com)。
不幸的是,尽管我们非常小心地编写代码,确保线程正确访问共享内存等等,但我们的shell命名空间扩展仍然偶尔会崩溃。Explorer主进程在使用或未使用我们的shell命名空间扩展期间崩溃。
我们使用了各种工具,如AQTime Pro来排除故障,但没有报告任何内存覆盖或其他类似的访问问题。这只留下一个罪犯:VCL不是线程安全的!
事实上,我们正在使用VCL作为我们的shell命名空间扩展的一部分; Explorer中的文件列表实际上是一个托管控件,在我们自己的shell命名空间扩展的情况下,它实际上是一个VCL窗口。经过多个开发代数后,我们现在甚至在怀疑这是否首先是允许的场景...
主应用程序对象甚至不存在于我们的shell命名空间扩展DLL中。使用TThread.Synchronize会死锁Explorer,因为没有任何主VCL线程被创建。我们需要手动创建一个主VCL线程(如何?) - 可能在另一个DLL中 - 并通过该DLL重新路由我们所有的UI创建/更新/销毁吗?
请记住,Explorer可能显示任意数量包含我们的VCL窗口的窗口。根据目标系统的配置,Explorer也可以作为多个独立进程或单个进程运行。
我们基于John Lam的起点构建了我们的shell命名空间扩展(正如大多数Delphi shell命名空间开发人员所知道的)。当然,正如您在最终产品中看到的那样,对这个起点进行了重大修改。 John Lam在他的幻灯片和示例项目中甚至没有讨论VCL线程不安全的问题。
我们还尝试过使用多个版本的ShellPlus组件。他们做了一些出色的工作,但不幸的是,在我们的经验中,即使基于他们的代码的非常基本的努力也比我们自己的代码提供了明显更差的结果。
ShellPlus实际上还提供了使用Explorer自己预定义的主机窗口的功能,而不是创建自定义VCL窗口;虽然这可能会避开任何VCL线程问题,但在我们的经验中,即使这也不是一个可行的解决方案 - 因为ShellPlus shell命名空间扩展始终比我们自己编写的代码不稳定,无论是否使用VCL窗口。
因此,首先问题是理论性的:VCL是否可以用于使用Explorer中的VCL窗口作为进程主机的shell命名空间扩展中?
如果可以,如何处理此场景中的VCL线程安全问题?