好吧,长话短说我有一个处理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,伪代码,实际代码...都赞赏。我正在努力坚持我认为最佳实践,尽管我也认为编程是一种艺术形式,我的最佳实践可能是别人的恐怖故事。
那么 - 你会怎么做?如果我需要澄清,请告诉我:))
答案 0 :(得分:3)
回到Windows API编程的旧时代,我们有时会使用RegisterWindowMessage
来注册一个唯一的消息ID(可能只有我们的窗口知道如何处理)。然后,我们可以通过使用PostMessage
的窗口句柄调用HWND_BROADCAST
来触发来自其他应用程序的窗口,并且msg
参数是该唯一消息值。如果要在进程之间共享的所有内容都可以放入两个DWORD
值(wparam
和lparam
),那么这非常有用。如果您分配全局内存并将引用作为参数之一传递,则可以共享更多数据。
.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进程中等待它(在单独的线程中)?