Shell命名空间扩展非常复杂。过去10年来,我们一直在构建shell命名空间扩展;最新版本是MagicRAR(www.magicrar.com)中的存档文件夹功能。
不幸的是,我们的shell命名空间扩展仍然偶尔会崩溃,尽管编码非常谨慎,确保线程正确访问共享内存等等。 Explorer主机进程在使用我们的shell命名空间扩展期间或之外崩溃。
我们使用各种工具(如AQTime Pro)来解决我们的shell命名空间扩展代码问题。报告没有内存覆盖或其他类似的访问问题。这只留下一个罪魁祸首:VCL不是线程安全的!
实际上,我们使用VCL作为shell命名空间扩展的一部分; Explorer中的文件列表实际上是一个托管控件,在我们自己的shell命名空间扩展的情况下,它实际上是一个VCL窗口。我们现在甚至想知道(经过多代开发)这是否是一个允许的场景......
主应用程序对象甚至不存在于我们的shell命名空间扩展DLL中。使用TThread.Synchronize deadlocks Explorer,因为尚未在任何地方创建主VCL线程。我们是否需要手动创建一个主VCL线程(如何?) - 可能在另一个DLL中 - 并通过该DLL重新路由所有UI创建/更新/销毁?
请记住,资源管理器可能会显示包含我们的VCL窗口的任意数量的窗口。资源管理器也可以作为多个独立进程运行,也可以作为单个进程运行,具体取决于目标系统的配置。
我们已将我们的shell命名空间扩展基于John Lam的起点(正如大多数Delphi shell命名空间开发人员所知)。当然,正如您在最终产品中所看到的,对此起点进行了大量修改。 John Lam甚至从未在他的幻灯片和示例项目中讨论过VCL在线程不安全的问题。
在过去十年中,我们还尝试使用多个版本的ShellPlus组件。他们做了一些出色的工作,但不幸的是,根据我们的经验,即使是基于代码的非常基础的工作也提供了比我们自己的代码更糟糕的结果。
ShellPlus实际上还提供了使用资源管理器自己的预定义主机窗口的功能,而不是创建自定义VCL窗口;虽然这可能会避开任何VCL线程问题,但根据我们的经验,即使这不是一个可行的解决方案 - 因为ShellPlus shell名称空间扩展一直不如我们的自制代码稳定,无论VCL是否窗口化。
首先是这样;这个问题是理论上的问题 - VCL可以用在shell命名空间扩展中,它使用Explorer中的VCL窗口作为进程主机吗?
如果是这样,在这种情况下如何处理VCL线程无安全问题?
答案 0 :(得分:4)
VCL确实不是线程安全的。在VCL应用程序外运行并不能解除该规则。缺乏主要的VCL线程只会让它变得更糟; VCL控件期望在主线程的上下文中运行,并且通常没有这样的线程,也不存在。您正在使用的控件访问各种全局变量而没有任何同步保护,并且没有什么可以做的就是修补任何VCL控件使用的所有单元。
使用常规Windows API技术,而不是VCL函数,在Explorer中创建和操作窗口。
你可以通过确保某些东西在被告知时检查队列来解决你的同步挂起,但是如果没有“主”线程,你不清楚你将与进行同步,所以{{1可能不是这项工作的正确工具。
答案 1 :(得分:0)
我们终于能够解决这个问题了。 固定的shell命名空间扩展将在即将推出的MagicRAR 9.0中展出。 问题确实与VCL有关 - 否则我们的代码完全没问题。 对于其他试图使用Delphi构建shell命名空间扩展的人:
是的,您可以使用Delphi构建shell命名空间扩展。 但是 - 如果你使用的是VCL,你会遇到无数的随机崩溃和不稳定。 AND - 如果你不使用VCL,那么使用Delphi就没什么意义了。 好消息是你不需要修补VCL来源。只需使用专用的VCL线程。