进程间通信

Wim*_*ink 14 delphi winapi ipc delphi-2007

我有两个应用程序:X和Y.X
是主应用程序,它处理大量的XML文件.它有超过10年的历史,已经使用了六种技术来存储,处理和处理这些XML文件.
Y是我正在开发的调试工具,它可以以更易于阅读的形式处理和显示XML文件.基本上,它只有一组样式表,可以检测XML格式,如果它识别格式,它会将XML转换为HTML,它显示在TWebBrowser组件中.

问题:
当Y处于活动状态时,我希望X将其执行的任何XML发送到Y以进行显示.但只有当Y在运行时!如果Y没有运行,X就不会做任何事情.
Y的检测需要在任何时刻完成,并且需要快速.我考虑过使用TCP/IP通信,但是由于缺少Y而造成的延迟太长了.特别是因为有时会处理很多XML.与命名管道和类似的基于网络的解决方案相同的问题.我需要快速确定Y是否正在运行且可用,如果是,请快速发送XML然后继续X.
我还考虑使Y成为基于COM的应用程序,或者可能添加基于COM的DLL,其中包含允许的事件进程间通信.DLL解决方案会很有趣,因为它会向X公开一个方法来上传XML文件,然后向Y发送一个事件来处理XML.这似乎是最好的选择虽然我还需要检查DLL是否已注册.如果没有,那么X甚至无法调用它!
应用程序X也将由不会收到Y或其他DLL的客户使用,因此在大多数情况下,DLL将不会被注册.(正如我所说,这意味着在调试期间提供帮助......)

但也许还有其他选择?TCP/IP太慢,COM有点过于复杂.


X和Y将在同一系统上运行.或者只是X将在系统上,Y完全丢失.


关于使用内存映射文件......虽然实用,但我需要记住,大多数情况下,Y不会运行,因此MMF会浪费内存.X中的XML数据最大可达4 MB,因此在内存中具有此大小的多个块有点矫枉过正.它可用于在X和Y之间发送状态消息,但内存有时是应用程序X的一个问题.虽然MMF可以连接到物理文件,但我试图避免写入任何临时文件.
这是一个很好的解决方案,但我担心不够好.


我认为还有一些额外的解释.应用程序X是一个应用程序,将使用几个小时,用户执行大量操作,转换为大量处理的XML数据.应用程序X是一个桌面应用程序,它与多个Web应用程序(REST),Web服务(SOAP)和其他应用程序进行通信,其中大部分是通过XML进行的.
应用程序Y只是为了窥视X正在运行的进程.基本上,X工作了20分钟,Y弹出.从那一刻开始,X应该开始向Y发送XML,直到Y再次消失或者X终止.在大多数情况下,Y只会运行以捕获正在运行的任务的一小部分,甚至可能多次启动.但我可能会想到整个方向都是错误的.也许X应该是Y注册的服务器......当Y找不到X时,这不是一个真正的问题.但是X找不到Y不能导致延迟或其他问题...

Run*_*ner 11

看看我的IPC:

http://www.cromis.net/blog/downloads/cromis-ipc/

它快速,免费且具有可设置的超时,因此您可以将其设置为非常小的量(例如50ms).因为它非常快(典型的消息循环请求 - >进程 - >响应时间不到1毫秒,大约0.1毫秒),您可以有非常小的超时.它有客户端服务器构建,因此很多客户端没有问题.它运行线程与后面的任务池,因此它不会冻结您的程序,它具有非常灵活的数据包,以方便写入/读取数据.

如前所述,如果调试器正在运行,您甚至可以使用其他方法进行检查.

  • 检查过程
  • 检查进程的主窗口
  • 使用互斥锁
  • ...


Ste*_*end 6

您可以让X将其输出写入内存映射文件 - 如果数据正在运行,Y可以检索数据.这样X不关心Y是否正常.

X可以在已知位置写入某种控制信息(例如,存储从映射文件中的偏移0开始的最后1000个写入的XML的偏移),并使用该文件的其余部分作为原始数据的循环缓冲区.

如果您需要Y作为X中操作的决定因素,请让Y创建映射文件,然后使用其存在/不存在来检查"通道"X侧的数据生成.没有为创作者和第二用户的示例代码在这里.


Ken*_*ite 6

你可以更简单地做到这一点,因为你只是试图找出一个应用程序是否正在从另一个应用程序运行.只要它们由同一个用户在同一台​​机器上运行,您就可以让X简单地使用FindWindow()来查看Y当前是否正在运行.只要确保给Y一个有意义的名字(在下面的示例中,它是TXMLFormatterForm):

var
  XMLWindow: HWnd;
begin
  XMLWindow := FindWindow('TXMLFormatterForm', nil);
  if XMLWindow > 0 then
    // Y is running
end;
Run Code Online (Sandbox Code Playgroud)

你也可以使用Y的窗口标题(标题),只要你确定它是独特的:

XMLWindow := FindWindow(nil, 'Workshop Alex's XML Formatter');
Run Code Online (Sandbox Code Playgroud)