带表格的 IPC?
我想制作IPC,但我不能使用阻塞机制(SendMessage、PIPE、TCP),并且我不想使用线程(更多错误源)或存储数据(例如文件、注册表)。
这是每台电脑上的2-4个软件,我想同步“消息存在”。
它是什么?我解释一下。 每个应用程序都使用相同的数据库。他们通过两个查询定期读取“消息”,并查看“正常”和“警报”消息何时到达,或者何时全部打开和读取。 但其中之一是“选择的”,受互斥体保护,它控制托盘图标和气球提示。当消息到达时,它会反映在托盘上。 当这个应用程序死掉时,另一个应用程序会尝试获取互斥体并控制托盘。
我想用IPC来表示“master”,如果状态发生变化(新消息到达,或者所有消息被读取),master就知道这一点,我们避免这种情况: 主人显示托盘和气球,用户在另一个应用程序中阅读消息。在这种情况下主人并不知道,并继续显示“新消息”控件。或者主人读完了所有内容,但有新消息到达。这个时候主人就必须将此事告知。 因为检查周期是:正常消息 - 5 分钟,警报 - 2 分钟。
那么:为什么我不使用阻塞 IPC,例如 SendMessage? 因为如果主程序启动一个大查询(5分钟),那么其他应用程序将在这段时间内被阻止.. :-(
之前我尝试过临时文件、注册表写入,但每个应用程序都有“清理”的问题,所以数据剩余...
然后我有一个想法,每个表单对于“EnumWindows”都是可见的,如果消息存储在Title中,我只使用该表单的Handle执行PostMessage,并且Master可以读取Title,处理消息。 如果 15 分钟过去了,我们将忽略此消息,并且“消息”窗口将被销毁。
好吧,好吧,这并不优雅,但我不知道有什么方法可以不在文件中存储任何内容,并且不能阻止(异步) - 没有线程地狱。
proc Send(Info : string):
handles = EnumAndFindHandles();
for handle in handles:
o = CreateMessageForm(handle, Info);
PostMessage(WM_MYMSG, handle, 11111, integer(o.Handle));
proc Recv(var Msg):
if IsHandleValid(Msg.lParam) and ClassNameIsGood(Msg.lParam):
txt = ReadWindowText(Msg.lParam);
if txt > '':
...
我想知道两件事: 1.) 您知道在什么情况下此通信可能会失败吗? (标题丢失、更改或其他可能阻碍这种方式的事情)? 2.)据我所知,EnumWindows 中只有表单可见?您知道如何使用另一个控件来做到这一点吗?
感谢您的任何想法、好的信息、建议!
DD
I want to make IPC, but I cannot use blocking mechanism (SendMessage, PIPE, TCP), and I don't wanna use Threads (more source of errors), or storing the data (files, registry for example).
Here is 2-4 softwares in every PC, and I want to synchronize the "message existance".
What is it? I explain it.
Every app is uses same database. They are periodically read the "messages" with two queries, and see when "normal" and "alarm" message arrived - or when they are all opened and read.
But one of them are the "chosen", protected with mutex, and it control a trayicon, and balloon hint. When message arrived, it reflected on tray.
When this app die, another trying to get the mutex, and control the tray.
I want to use the IPC to say the "master" if the state changed (new message arrived, or all messages read) to master know about this, and we avoid this situation:
Master show the tray and balloon, and user read the messages in another app. In this case the master don't know about it, and continue to show the "new messsage" controls. Or master read all, but a new message arrived. In this time the master must inform about this.
Because the checking periods are: normal message - 5 minutes, alarm - 2 minutes.
So: why I don't use blocking IPC, like SendMessage?
Because if the master starts a big query (5 minutes) then the another apps are blocked for these time.. :-(
Previously I tried with temp files, registry writing, but every of them is have the problem of "cleaning", so data remaining...
Then I have an idea the every form is visible for "EnumWindows". If messages are stored in Title, I only do PostMessage with the Handle of this form, and the Master can read the Title, process the message.
If 15 minutes passed, we ignore this message, and the "message" window destroyed.
Ok, ok, it is don't elegant, but I don't know about any way that don't store anything in files, and cannot block (async) - without threading hell.
proc Send(Info : string):
handles = EnumAndFindHandles();
for handle in handles:
o = CreateMessageForm(handle, Info);
PostMessage(WM_MYMSG, handle, 11111, integer(o.Handle));
proc Recv(var Msg):
if IsHandleValid(Msg.lParam) and ClassNameIsGood(Msg.lParam):
txt = ReadWindowText(Msg.lParam);
if txt > '':
...
I want to know two things:
1.) Do you know any situation when this communication can failed? (Caption is missing, changed or other thing that can blocking this way)?
2.) As I see only the Forms can visible in EnumWindows? Do you know a way to do this with another control?
Thanks for any ideas, good informations, suggestions!
dd
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
对我来说,听起来 内存映射文件 可以一个简单的解决方案:在应用程序之间共享一块内存,就像临时文件一样。您说您考虑过基于文件的方法,但不喜欢它们留下的痕迹。对于内存映射文件,跟踪将位于页面文件中,这可能不像注册表或临时文件那么重要。
For me it sounds like memory mapped files could be a simple solution: share a block of memory between your applications, just like with a temp file. You said you considered file-based methods but don't like the traces they leave. With memory mapped files the traces will be in the page file, which might not be such a big deal as with the registry or temporary files.
考虑使用无状态方法。
以下是一些好处:
即使您仍然需要本地 IPC,考虑迁移到网络友好的架构可能会让您的未来更轻松。如果需要,它还会准备您的应用程序以迁移到 SOA。例如,我们的无状态客户端-服务器 ORM 能够与 GDI 消息进行本地通信(如您所建议的)或命名管道,或远程使用 HTTP/1.1。
Consider using a StateLess aproach instead.
Here are some benefits:
Even if you still need local IPC yet, consider moving to a network-friendly architecture may make your future easier. It also prepare your application to move to SOA if needed. For instance, our stateless Client-Server ORM is able to communicate locally with GDI messages (as you propose) or named pipes, or remotely using HTTP/1.1.