我为问题的长度道歉,但我相信没有背景很难理解“为什么”。
背景:我有两个应用程序在 Windows Embedded Standard 7 环境中运行。它们应该是机器上运行的仅有的两个应用程序。一个叫做“Controller”,用 C++ 编写,另一个叫做“DBconnector”,用 C# 编写。这不是新代码。它已经活跃使用和开发了近 20 年。
该软件的目的是运行用于生产零件的制造机器。如果程序崩溃,这些机器又大又危险。很久以前,我发现如果网络由于某种原因出现故障,应用程序中的所有线程都会停止——不仅仅是网络线程。这是灾难性的,因为在极少数情况下让控制器处于错误继电器开启的状态可能会导致机器爆炸。注意:现在软件和硬件中添加了一些东西来防止这种情况。虽然这种危险不再存在,但稳定性仍然非常重要。我从不希望操作员陷入无法按下重置按钮的状态。我当时的解决方案是将网络任务转移到一个单独的应用程序中。该操作系统当时是基于 Windows XP 的。
这两个程序的开发出现了分歧,一个控制机器的控制器,Controller,被设计用于极端稳定性,而另一个,DBconnector,是发生网络和大多数文件 I/O 等危险事情的地方。使用它们都可以访问的内存映射文件来促进两个程序之间的通信。我在共享两个程序之间可能需要的窗口句柄或进程 ID 或任何其他数据时没有问题。
这是我的问题。 如何让 Controller 应用程序显示 DBconnector 的 GUI?例如,我已经开始向 Controller 添加功能,要求 DBconnector 显示保存在公司服务器上的网站上的质量控制表。我希望操作员能够直接在机器上拉出质量控制表。操作员目前仅与 Controller 应用程序交互。我不希望控制器能够访问网络。此外,C# 有一些工具可以轻松显示网页。在我看来,这样做的地方是 DBconnector。问题是 DBconnector 在后台运行,当前用户无法看到或访问。所以,问题是如何解决这个问题。
我尝试的第一个选项是告诉 DBconnector 挺身而出并将 Controller 置于后台。然后,当用户完成后,Controller 回到前面。我已经使用一些技巧让它工作,但它是不一致的。我使用的技巧是最小化然后最大化 DBconnector,这似乎在大多数情况下将它带到了前面,并尝试将注意力集中在一个或另一个上。仍然可能有一种方法可以做到这一点,但它需要是一致的。
第二个选项是在 Controller 的一个窗口内运行 DBconnector 应用程序。我不知道该怎么做。我考虑过使用 ATL 或 COM,但我认为它们作为控制器进程中的线程而不是作为单独的应用程序运行。
我考虑的第三个选项是在 Controller 中创建一个窗口,该窗口使用 Windows 消息句柄拦截所有用户输入消息并将其直接传递给 Dbconnector,并在 DBconnector 无效时截取 DBconnector 的屏幕截图并将其传递给内存映射文件。目前,这就是我正在努力的方向。
关于如何更好地执行第一个和最后一个选项,或者根本如何执行第二个选项,或者我错过的其他解决方案有什么建议吗?请记住,我们当前的硬件运行的是 Windows Embedded Standard 7。该项目目前在 Visual Studio 2015 中。我认为 C++ 窗口技术是使用最初从 2003 年左右开始的库实现的 MFC。DBconnector 在 C# 的 .NET 框架 4 中。