C#跨IPC的事件

时间:2011-02-08 22:23:48

标签: c# .net events windows-services ipc

好吧,长话短说我有一个处理Win32_VolumeChangeEvent的Windows服务,并将USB磁盘设备到达记录到事件日志和SQL数据库。另一个组件是隐藏的UI(WinForms),它在登录时加载到用户会话中 - 这会弹出一个消息框,提醒用户公司有关USB密钥等的政策.AFAIK,这是最好的方式,因为服务不能在交互模式下运行时间更长。

Anywho ...在架构上,这个小东西的v1运行UI组件处理WndProc消息以进行设备插入,然后通过IPC(命名管道)将设备标识符传递给将处理WMI方法/ EventLog写入的服务(如并非所有用户都拥有本地管理员权限)。这有一个缺点是UI元素被处理杀死,不再检测设备插入。

因此,当前版本是该服务处理Win32_VolumeChangeEvents并从设备获取所需的详细信息,然后记录到EventLog和SQL。一切都很出色,完美无缺。除了现在我想知道触发UI显示弹出窗口的最佳方法是什么。

我已经围绕谷歌进行了研究,在这里寻找关于通过IPC进行事件的想法,所以我可以从UI组件订阅一个事件并在服务中激活它,但是我发现没有多少跳出来有帮助。我也受限于.net2,所以WCF不在图片中(尽管如果你想这样做我不害怕p / invoke。)

因此。你会怎么做?链接,思想,ramblings,伪代码,实际代码...都赞赏。我正在努力坚持我认为最佳实践,尽管我也认为编程是一种艺术形式,我的最佳实践可能是别人的恐怖故事。

那么 - 你会怎么做?如果我需要澄清,请告诉我:))

2 个答案:

答案 0 :(得分:3)

回到Windows API编程的旧时代,我们有时会使用RegisterWindowMessage来注册一个唯一的消息ID(可能只有我们的窗口知道如何处理)。然后,我们可以通过使用PostMessage的窗口句柄调用HWND_BROADCAST来触发来自其他应用程序的窗口,并且msg参数是该唯一消息值。如果要在进程之间共享的所有内容都可以放入两个DWORD值(wparamlparam),那么这非常有用。如果您分配全局内存并将引用作为参数之一传递,则可以共享更多数据。

.NET仍然可以实现。当然,调用PostMessage没问题。至于在UI代码中处理消息,您必须覆盖表单的WndProc。有关示例,请参阅How do I send/receive windows messages between VB6 and c#?

您可以对命名事件执行某些操作,但这只会通知UI已发生某些更改。它实际上不会告诉你发生了什么。我想,如果只有一小部分可能的事件,你可以有多个事件,但这很快就会变得复杂。

您可以使用命名事件路由并使用共享内存(内存映射文件)来共享状态。

或者,您可以设置套接字,命名管道,TcpListener / TcpClient,甚至是UdpClient。所有这些都应该有效,具有不同程度的复杂性和/或可靠性。

答案 1 :(得分:1)

我想到的唯一想法是让服务定期检查UI应用程序的状态,如果已经被杀死则重新启动它。似乎没有标准模块可以在用户会话中运行,并让服务向此模块发送通知。存在第三方解决方案,但它们可能会被杀死(并不是说应该安装它们才能使用)。

更新:重新阅读问题后,我认为您的UI可能不会收到Windows消息,因此您需要其他机制。为什么不在服务中创建Semaphore同步对象并在UI进程中等待它(在单独的线程中)?