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