Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/271.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
跨IPC的C#事件_C#_.net_Events_Windows Services_Ipc - Fatal编程技术网

跨IPC的C#事件

跨IPC的C#事件,c#,.net,events,windows-services,ipc,C#,.net,Events,Windows Services,Ipc,好的,长话短说,我有一个Windows服务,它处理Win32_VolumeChangeEvent并将USB磁盘设备到达记录到事件日志和SQL数据库中。另外一个组件是一个隐藏的UI(WinForms),它在登录时加载到用户会话中-这会弹出一个消息框,提醒用户有关USB密钥等的公司政策。好了,这是最好的方法,因为服务不能再以交互模式运行 不管是谁。。。在体系结构上,这个小东西的v1运行时,UI组件处理WndProc消息以进行设备插入,然后通过IPC(命名管道)将设备标识符传递给服务,该服务将处理WM

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

不管是谁。。。在体系结构上,这个小东西的v1运行时,UI组件处理WndProc消息以进行设备插入,然后通过IPC(命名管道)将设备标识符传递给服务,该服务将处理WMI方法/事件日志写入(因为并非所有用户都具有本地管理员权限)。这样做的缺点是UI元素被进程终止,不再检测设备插入

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

我已经在Google和这里进行了研究,寻找通过IPC进行事件处理的想法,这样我就可以从UI组件订阅事件并在服务中启动它,但我没有发现有什么帮助。我还受.net2的限制,所以WCF是不可能的(尽管如果您想这样做,我并不害怕p/invoke)

所以。你会怎么做?链接,想法,漫谈,伪代码,实际代码。。。一切都很感激。虽然我也认为编程是一种艺术形式,而且我的最佳实践可能是别人的恐怖故事,但我还是努力坚持我认为的最佳实践


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

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


更新:在重读这个问题后,我认为可能你的用户界面没有收到windows消息,所以你需要另一种机制。为什么不在服务中创建一个同步对象,并在UI进程中等待它(在单独的线程中)

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


更新:在重读这个问题后,我认为可能你的用户界面没有收到windows消息,所以你需要另一种机制。为什么不在服务中创建一个同步对象,并在UI进程中等待它(在单独的线程中)

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

这在.NET中仍然是可能的。当然,调用
PostMessage
不会有问题。至于在UI代码中处理消息,您必须覆盖表单的
WndProc
。有关示例,请参见

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

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


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

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

这在.NET中仍然是可能的。当然,调用
PostMessage
不会有问题。至于在UI代码中处理消息,您必须覆盖表单的
WndProc
。有关示例,请参见

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

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