侦听另一个应用程序中的事件

Posted

技术标签:

【中文标题】侦听另一个应用程序中的事件【英文标题】:Listen for events in another application 【发布时间】:2010-09-06 06:46:26 【问题描述】:

假设我有两个用 C# 编写的应用程序。第一个是引发名为“OnEmailSent”的事件的第三方应用程序。

第二个是我编写的自定义应用程序,我想以某种方式订阅第一个应用程序的“OnEmailSent”。

有什么方法可以让我以某种方式将第二个应用程序附加到第一个应用程序的实例以侦听“OnEmailSent”事件?


为了进一步澄清,我的具体情况是我们有一个用 c# 编写的自定义第三方应用程序,它引发了一个“OnEmailSent”事件。我们可以使用反射器看到事件存在。

我们想要做的是在这个组件发送电子邮件时执行一些其他操作。

我们能想到的最有效的方法是能够使用安德斯建议的某种形式的 IPC,并监听第三方组件引发的 OnEmailSent 事件。

由于该组件是用 C# 编写的,我们正在考虑编写另一个 C# 应用程序,该应用程序可以将自身附加到执行进程,并且当它检测到 OnEmailSent 事件已引发时,它将执行它自己的事件处理代码。


我可能遗漏了一些东西,但根据我对远程处理工作原理的理解,需要有一个服务器来定义客户端可以订阅的某种合同。

我更多地考虑有人编写了一个独立的应用程序,例如 Outlook,它公开了我想从另一个应用程序订阅的事件。

我想我正在考虑的场景是 .net 调试器,以及它如何附加到执行程序集以在运行时检查代码。

【问题讨论】:

【参考方案1】:

为了让两个应用程序(独立的进程)交换事件,它们必须就这些事件的通信方式达成一致。有许多不同的方法可以做到这一点,具体使用哪种方法可能取决于架构和上下文。这种进程间信息交换的总称是Inter-process Communication (IPC)。存在许多执行 IPC 的标准方法,最常见的是文件、管道、(网络)套接字、remote procedure calls (RPC) 和共享内存。在 Windows 上,使用 window messages 也很常见。

我不确定这对于 Windows 上的 .NET/C# 应用程序是如何工作的,但在本机 Win32 应用程序中你可以hook on to the message loop of external processes and "spy" on the messages they are sending。如果您的程序在调用所需函数时生成消息事件,这可能是一种检测它的方法。

如果您自己实现这两个应用程序,您可以选择使用您喜欢的任何 IPC 方法。网络套接字和更高级别的基于套接字的协议(如 HTTP、XML-RPC 和 SOAP)现在非常流行,因为它们也允许您在不同的物理机器上运行应用程序(假设它们是通过网络连接的)。

【讨论】:

【参考方案2】:

您可以尝试Managed Spy 并进行编程访问ManagedSpyLib

ManagedSpyLib 引入了一个类 称为控制代理。 ControlProxy 是 一个表示 System.Windows.Forms.Control 中 另一个过程。 ControlProxy 允许 您获取或设置属性和 像您一样订阅事件 在目的地内运行 过程。将 ManagedSpyLib 用于 自动化测试,事件记录 兼容性,跨进程 通信或白盒测试。

但这可能对您不起作用,取决于 ControlProxy 是否可以通过某种方式访问​​您在第三方应用程序中所追求的事件。

你也可以使用Reflexil

Reflexil 允许 使用强大的 IL 修改 Jb 编写的 Mono.Cecil 库 伊万。 Reflexil 作为 Reflector 插件运行,并且 特别针对 IL 代码 处理。它通过 提出完整的指令 编辑器并允许 C#/VB.NET 代码 注射。

【讨论】:

【参考方案3】:

您可以使用远程处理或 WCF。见http://msdn.microsoft.com/en-us/library/aa730857(VS.80).aspx#netremotewcf_topic7。

【讨论】:

【参考方案4】:

来自该第三方应用程序的 OnEmailSent 事件的性质是什么?我的意思是,你怎么知道应用程序正在触发这样的事件?

如果打算进行进程间通信,你应该问自己的第一个问题是:真的有必要吗?

不怀疑你的动机,如果你真的需要进行进程间通信,你将需要某种机制。名单很长,很长。从简单的 WM_DATA 消息到自定义 TCP 协议,再到需要额外基础设施的非常复杂的 Web 服务。

这带来了一个问题,您到底想做什么?您无法控制的第三方应用程序是什么?

此外,调试器有一种非常具有侵入性的调试进程的方式。不要期望这是所有其他应用程序使用的标准进程间机制。其实不然。

【讨论】:

【参考方案5】:

您可以使用 SQL Server 2005 查询更改通知实现类似的场景,方法是使用 .NET 应用程序维护一个持久的 SqlConnection,该应用程序在数据库中的数据更改之前一直阻塞。

见http://www.code-magazine.com/article.aspx?quickid=0605061。

【讨论】:

【参考方案6】:

WM_COPYDATA 也可能是可能的,请参阅https://social.msdn.microsoft.com/Forums/en-US/eb5dab00-b596-49ad-92b0-b8dee90e24c8/wmcopydata-event-to-receive-data-in-form-application?forum=winforms 我将它用于类似的 Purose(通知选项已更改)

在我们的 C++/Cli-scenario (MFC-) 程序中,通过 WM_COPYDATA 与 COPYDATASTRUCT-Member lpData 中的 Information-String 进行通信 (参数列表如“Caller=xyz Receiver=abc Job=dosomething”)。 C#-App 也可以接收 WM_COPYDATA 消息,如链接所示。从 C# 发送 WM_COPYDATA(到已知的 Mainframe-Handle)是由 cpp/cli-Assembly 完成的(我没有证明如何在 C# 中发送 WMCOPYDATA)。

PS 在 Cpp/Cli 中,我们将 AfxGetMainWnd()->m_hWnd 作为 WMCOPYDATA-Message 的 WPARAM 发送,而在 C# (WndProc) 中,m.WParam 可用作发送 WM_COPYDATA 的地址

【讨论】:

您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。

以上是关于侦听另一个应用程序中的事件的主要内容,如果未能解决你的问题,请参考以下文章

在循环中单击另一个元素时将事件侦听器添加到元素

使用 StaticResource 和 MouseDown 处理程序时事件侦听器上的 Nullpointer 错误

如何在 Shiny eventReactive 处理程序中侦听多个事件表达式

macOS 中的事件通知

单击 ListActivity 中的事件侦听器 [重复]

获取视图的触摸侦听器并在另一个视图上调用触摸事件